ossrv_pub/boost_apis/boost/program_options/eof_iterator.hpp
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 // Copyright Vladimir Prus 2004.
       
     2 // Distributed under the Boost Software License, Version 1.0.
       
     3 // (See accompanying file LICENSE_1_0.txt
       
     4 // or copy at http://www.boost.org/LICENSE_1_0.txt)
       
     5 
       
     6 #ifndef BOOST_EOF_ITERATOR_VP_2004_03_12
       
     7 #define BOOST_EOF_ITERATOR_VP_2004_03_12
       
     8 
       
     9 #include <boost/iterator/iterator_facade.hpp>
       
    10 
       
    11 namespace boost {
       
    12 
       
    13     /** The 'eof_iterator' class is useful for constructing forward iterators 
       
    14         in cases where iterator extract data from some source and it's easy 
       
    15         to detect 'eof' -- i.e. the situation where there's no data. One 
       
    16         apparent example is reading lines from a file.
       
    17         
       
    18         Implementing such iterators using 'iterator_facade' directly would
       
    19         require to create class with three core operation, a couple of 
       
    20         constructors. When using 'eof_iterator', the derived class should define 
       
    21         only one method to get new value, plus a couple of constructors.
       
    22 
       
    23         The basic idea is that iterator has 'eof' bit. Two iterators are equal 
       
    24         only if both have their 'eof' bits set. The 'get' method either obtains
       
    25         the new value or sets the 'eof' bit.
       
    26 
       
    27         Specifically, derived class should define:
       
    28 
       
    29         1. A default constructor, which creates iterator with 'eof' bit set. The
       
    30         constructor body should call 'found_eof' method defined here.
       
    31         2. Some other constructor. It should initialize some 'data pointer' used
       
    32         in iterator operation and then call 'get'.
       
    33         3. The 'get' method. It should operate this way:
       
    34             - look at some 'data pointer' to see if new element is available;
       
    35               if not, it should call 'found_eof'.
       
    36             - extract new element and store it at location returned by the 'value' 
       
    37                method.
       
    38             - advance the data pointer.
       
    39 
       
    40         Essentially, the 'get' method has the functionality of both 'increment' 
       
    41         and 'dereference'. It's very good for the cases where data extraction 
       
    42         implicitly moves data pointer, like for stream operation.         
       
    43     */
       
    44     template<class Derived, class ValueType>
       
    45     class eof_iterator : public iterator_facade<Derived, const ValueType,
       
    46                                                 forward_traversal_tag>
       
    47     {
       
    48     public:
       
    49         eof_iterator()
       
    50         : m_at_eof(false)
       
    51         {}
       
    52 
       
    53     protected: // interface for derived
       
    54 
       
    55         /** Returns the reference which should be used by derived
       
    56             class to store the next value. */
       
    57         ValueType& value()
       
    58         {
       
    59             return m_value;
       
    60         }
       
    61 
       
    62         /** Should be called by derived class to indicate that it can't
       
    63             produce next element. */
       
    64         void found_eof()
       
    65         {
       
    66             m_at_eof = true;
       
    67         }
       
    68         
       
    69 
       
    70     private: // iterator core operations
       
    71         friend class iterator_core_access;
       
    72     
       
    73         void increment() 
       
    74         {
       
    75             static_cast<Derived&>(*this).get();
       
    76         }
       
    77     
       
    78         bool equal(const eof_iterator& other) const
       
    79         {
       
    80             if (m_at_eof && other.m_at_eof)
       
    81                 return true;
       
    82             else
       
    83                 return false;
       
    84         }
       
    85         
       
    86         const ValueType& dereference() const
       
    87         {
       
    88             return m_value;
       
    89         }
       
    90 
       
    91         bool m_at_eof;
       
    92         ValueType m_value;        
       
    93     };
       
    94 }
       
    95 
       
    96 #endif
       
    97