blocxx
|
00001 /******************************************************************************* 00002 * Copyright (C) 2005, Vintela, Inc. All rights reserved. 00003 * Copyright (C) 2006, Novell, Inc. All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions are met: 00007 * 00008 * * Redistributions of source code must retain the above copyright notice, 00009 * this list of conditions and the following disclaimer. 00010 * * Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * * Neither the name of 00014 * Vintela, Inc., 00015 * nor Novell, Inc., 00016 * nor the names of its contributors or employees may be used to 00017 * endorse or promote products derived from this software without 00018 * specific prior written permission. 00019 * 00020 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00021 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00022 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00023 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00024 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00025 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00026 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00027 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00028 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00029 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00030 * POSSIBILITY OF SUCH DAMAGE. 00031 *******************************************************************************/ 00032 00033 00038 #ifndef BLOCXX_ENUMERATION_HPP_INCLUDE_GUARD_ 00039 #define BLOCXX_ENUMERATION_HPP_INCLUDE_GUARD_ 00040 #include "blocxx/BLOCXX_config.h" 00041 #include "blocxx/TempFileEnumerationImplBase.hpp" 00042 #include "blocxx/IntrusiveReference.hpp" 00043 00044 #include <iterator> // for the iterator tags 00045 00046 namespace BLOCXX_NAMESPACE 00047 { 00048 00049 template <class T> 00050 class TempFileEnumerationImpl : public TempFileEnumerationImplBase 00051 { 00052 public: 00053 TempFileEnumerationImpl() 00054 { 00055 } 00056 virtual ~TempFileEnumerationImpl() 00057 { 00058 } 00059 void nextElement(T& out) 00060 { 00061 throwIfEmpty(); 00062 out.readObject(*m_Data.rdbuf()); 00063 --m_size; 00064 } 00065 T nextElement() 00066 { 00067 throwIfEmpty(); 00068 T retval; 00069 retval.readObject(*m_Data.rdbuf()); 00070 --m_size; 00071 return retval; 00072 } 00073 void addElement( const T& arg ) 00074 { 00075 arg.writeObject(*m_Data.rdbuf()); 00076 ++m_size; 00077 } 00078 private: 00079 // Prevent copying or assignment 00080 TempFileEnumerationImpl( const TempFileEnumerationImpl<T>& ); 00081 TempFileEnumerationImpl<T>& operator=( const TempFileEnumerationImpl<T>& ); 00082 }; 00083 00084 template <class T> 00085 class Enumeration 00086 { 00087 public: 00088 Enumeration() 00089 : m_impl( new TempFileEnumerationImpl<T> ) 00090 { 00091 } 00092 bool hasMoreElements() const 00093 { 00094 return m_impl->hasMoreElements(); 00095 } 00096 void nextElement(T& arg) 00097 { 00098 m_impl->nextElement(arg); 00099 } 00100 T nextElement() 00101 { 00102 return m_impl->nextElement(); 00103 } 00104 size_t numberOfElements() const 00105 { 00106 return m_impl->numberOfElements(); 00107 } 00108 void addElement(const T& arg) 00109 { 00110 m_impl->addElement(arg); 00111 } 00112 void clear() 00113 { 00114 m_impl->clear(); 00115 } 00116 bool usingTempFile() const 00117 { 00118 return m_impl->usingTempFile(); 00119 } 00120 private: 00121 IntrusiveReference< TempFileEnumerationImpl<T> > m_impl; 00122 }; 00123 00124 template <class T> 00125 class Enumeration_input_iterator 00126 { 00127 public: 00128 typedef Enumeration<T> enumeration_type; 00129 typedef std::input_iterator_tag iterator_category; 00130 typedef T value_type; 00131 typedef const T* pointer; 00132 typedef const T& reference; 00133 typedef ptrdiff_t difference_type; 00134 Enumeration_input_iterator() : m_enumeration(0), m_ok(false) 00135 { 00136 } 00137 Enumeration_input_iterator(enumeration_type& e) : m_enumeration(&e) 00138 { 00139 m_read(); 00140 } 00141 00142 // compiler generated copy ctor is what we want. 00143 // compiler generated copy-assignment operator= is what we want. 00144 00145 reference operator*() const 00146 { 00147 return m_value; 00148 } 00149 pointer operator->() const 00150 { 00151 return &(operator*()); 00152 } 00153 Enumeration_input_iterator& operator++() 00154 { 00155 m_read(); 00156 return *this; 00157 } 00158 Enumeration_input_iterator operator++(int) 00159 { 00160 Enumeration_input_iterator tmp = *this; 00161 m_read(); 00162 return tmp; 00163 } 00164 bool m_equal(const Enumeration_input_iterator& x) const 00165 { 00166 return(m_ok == x.m_ok) && (!m_ok || m_enumeration == x.m_enumeration); 00167 } 00168 private: 00169 enumeration_type* m_enumeration; 00170 T m_value; 00171 bool m_ok; 00172 void m_read() 00173 { 00174 m_ok = (m_enumeration && m_enumeration->hasMoreElements()) ? true : false; 00175 if (m_ok) 00176 { 00177 m_enumeration->nextElement(m_value); 00178 } 00179 } 00180 }; 00181 00182 template <class T> 00183 inline bool 00184 operator==(const Enumeration_input_iterator<T>& x, 00185 const Enumeration_input_iterator<T>& y) 00186 { 00187 return x.m_equal(y); 00188 } 00189 00190 template <class T> 00191 inline bool 00192 operator!=(const Enumeration_input_iterator<T>& x, 00193 const Enumeration_input_iterator<T>& y) 00194 { 00195 return !x.m_equal(y); 00196 } 00197 00198 template <class T> 00199 class Enumeration_insert_iterator 00200 { 00201 public: 00202 typedef Enumeration<T> enumeration_type; 00203 typedef std::output_iterator_tag iterator_category; 00204 typedef void value_type; 00205 typedef void difference_type; 00206 typedef void pointer; 00207 typedef void reference; 00208 Enumeration_insert_iterator(enumeration_type& e) : m_enumeration(&e) 00209 { 00210 } 00211 Enumeration_insert_iterator<T>& operator=(const T& value) 00212 { 00213 m_enumeration->addElement(value); 00214 return *this; 00215 } 00216 Enumeration_insert_iterator<T>& operator*() 00217 { 00218 return *this; 00219 } 00220 Enumeration_insert_iterator<T>& operator++() 00221 { 00222 return *this; 00223 } 00224 Enumeration_insert_iterator<T>& operator++(int) 00225 { 00226 return *this; 00227 } 00228 private: 00229 enumeration_type* m_enumeration; 00230 }; 00231 00232 template <class Container> 00233 inline Enumeration_insert_iterator<Container> Enumeration_inserter(Enumeration<Container>& x) 00234 { 00235 return Enumeration_insert_iterator<Container>(x); 00236 } 00237 00238 } // end namespace BLOCXX_NAMESPACE 00239 00240 #endif