Enumeration.hpp

Go to the documentation of this file.
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

Generated on Fri Jun 16 15:39:08 2006 for blocxx by  doxygen 1.4.6