blocxx

Enumeration.hpp

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