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