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