Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:38:55

0001 // Copyright 2009 (C) Dean Michael Berris <me@deanberris.com>
0002 // Copyright 2012 (C) Google, Inc.
0003 // Copyright 2012 (C) Jeffrey Lee Hellrung, Jr.
0004 // Distributed under the Boost Software License, Version 1.0. (See
0005 // accompanying file LICENSE_1_0.txt or copy at
0006 // http://www.boost.org/LICENSE_1_0.txt)
0007 //
0008 
0009 #ifndef BOOST_FUNCTION_INPUT_ITERATOR
0010 #define BOOST_FUNCTION_INPUT_ITERATOR
0011 
0012 #include <boost/config.hpp>
0013 #include <boost/assert.hpp>
0014 #include <boost/core/addressof.hpp>
0015 #include <boost/type_traits/conditional.hpp>
0016 #include <boost/function_types/is_function_pointer.hpp>
0017 #include <boost/function_types/result_type.hpp>
0018 #include <boost/iterator/iterator_facade.hpp>
0019 #include <boost/none.hpp>
0020 #include <boost/optional/optional.hpp>
0021 #include <boost/utility/result_of.hpp>
0022 
0023 #ifdef BOOST_RESULT_OF_USE_TR1
0024 #include <boost/type_traits/is_function.hpp>
0025 #endif
0026 
0027 namespace boost {
0028 
0029 namespace iterators {
0030 
0031     template <class Function, class Input>
0032     class function_input_iterator;
0033 
0034     namespace impl {
0035 
0036         // Computes the return type of an lvalue-call with an empty argument,
0037         // i.e. decltype(declval<F&>()()). F should be a nullary lvalue-callable
0038         // or function.
0039         template <class F>
0040         struct result_of_nullary_lvalue_call
0041         {
0042             typedef typename result_of<
0043 #ifdef BOOST_RESULT_OF_USE_TR1
0044                 typename boost::conditional<is_function<F>::value, F&, F>::type()
0045 #else
0046                 F&()
0047 #endif
0048             >::type type;
0049         };
0050 
0051         template <class Function, class Input>
0052         class function_object_input_iterator :
0053             public iterator_facade<
0054                 iterators::function_input_iterator<Function, Input>,
0055                 typename result_of_nullary_lvalue_call<Function>::type,
0056                 single_pass_traversal_tag,
0057                 typename result_of_nullary_lvalue_call<Function>::type const &
0058             >
0059         {
0060         public:
0061             function_object_input_iterator() {}
0062             function_object_input_iterator(Function & f_, Input state_ = Input())
0063                 : f(boost::addressof(f_)), state(state_) {}
0064 
0065             void increment() {
0066                 if (value)
0067                     value = none;
0068                 else
0069                     (*f)();
0070                 ++state;
0071             }
0072 
0073             typename result_of_nullary_lvalue_call<Function>::type const &
0074                 dereference() const {
0075                 if (!value)
0076                     value = (*f)();
0077                 return value.get();
0078             }
0079 
0080             bool equal(function_object_input_iterator const & other) const {
0081                 return f == other.f && state == other.state;
0082             }
0083 
0084         private:
0085             Function * f;
0086             Input state;
0087             mutable optional<typename result_of_nullary_lvalue_call<Function>::type> value;
0088         };
0089 
0090         template <class Function, class Input>
0091         class function_pointer_input_iterator :
0092             public iterator_facade<
0093                 iterators::function_input_iterator<Function, Input>,
0094                 typename function_types::result_type<Function>::type,
0095                 single_pass_traversal_tag,
0096                 typename function_types::result_type<Function>::type const &
0097             >
0098         {
0099         public:
0100             function_pointer_input_iterator() {}
0101             function_pointer_input_iterator(Function &f_, Input state_ = Input())
0102                 : f(f_), state(state_) {}
0103 
0104             void increment() {
0105                 if (value)
0106                     value = none;
0107                 else
0108                     (*f)();
0109                 ++state;
0110             }
0111 
0112             typename function_types::result_type<Function>::type const &
0113                 dereference() const {
0114                 if (!value)
0115                     value = (*f)();
0116                 return value.get();
0117             }
0118 
0119             bool equal(function_pointer_input_iterator const & other) const {
0120                 return f == other.f && state == other.state;
0121             }
0122 
0123         private:
0124             Function f;
0125             Input state;
0126             mutable optional<typename function_types::result_type<Function>::type> value;
0127         };
0128 
0129     } // namespace impl
0130 
0131     template <class Function, class Input>
0132     class function_input_iterator :
0133         public boost::conditional<
0134             function_types::is_function_pointer<Function>::value,
0135             impl::function_pointer_input_iterator<Function,Input>,
0136             impl::function_object_input_iterator<Function,Input>
0137         >::type
0138     {
0139         typedef typename boost::conditional<
0140             function_types::is_function_pointer<Function>::value,
0141             impl::function_pointer_input_iterator<Function,Input>,
0142             impl::function_object_input_iterator<Function,Input>
0143         >::type base_type;
0144     public:
0145         function_input_iterator(Function & f, Input i)
0146             : base_type(f, i) {}
0147     };
0148 
0149     template <class Function, class Input>
0150     inline function_input_iterator<Function, Input>
0151         make_function_input_iterator(Function & f, Input state) {
0152             typedef function_input_iterator<Function, Input> result_t;
0153             return result_t(f, state);
0154     }
0155 
0156     template <class Function, class Input>
0157     inline function_input_iterator<Function*, Input>
0158         make_function_input_iterator(Function * f, Input state) {
0159             typedef function_input_iterator<Function*, Input> result_t;
0160             return result_t(f, state);
0161     }
0162 
0163     struct infinite
0164     {
0165         infinite & operator++() { return *this; }
0166         infinite & operator++(int) { return *this; }
0167         bool operator==(infinite &) const { return false; };
0168         bool operator==(infinite const &) const { return false; };
0169     };
0170 
0171 } // namespace iterators
0172 
0173 using iterators::function_input_iterator;
0174 using iterators::make_function_input_iterator;
0175 using iterators::infinite;
0176 
0177 } // namespace boost
0178 
0179 #endif
0180