Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-18 08:47:27

0001 // (C) Copyright David Abrahams 2002.
0002 // (C) Copyright Jeremy Siek    2002.
0003 // (C) Copyright Thomas Witt    2002.
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 #ifndef BOOST_ITERATOR_TRANSFORM_ITERATOR_23022003THW_HPP
0008 #define BOOST_ITERATOR_TRANSFORM_ITERATOR_23022003THW_HPP
0009 
0010 #include <iterator>
0011 #include <type_traits>
0012 
0013 #include <boost/core/use_default.hpp>
0014 #include <boost/core/empty_value.hpp>
0015 #include <boost/iterator/iterator_adaptor.hpp>
0016 #include <boost/iterator/enable_if_convertible.hpp>
0017 #include <boost/iterator/detail/eval_if_default.hpp>
0018 
0019 namespace boost {
0020 namespace iterators {
0021 
0022 template<
0023     typename UnaryFunction,
0024     typename Iterator,
0025     typename Reference = use_default,
0026     typename Value = use_default
0027 >
0028 class transform_iterator;
0029 
0030 namespace detail {
0031 
0032 template< typename UnaryFunc, typename Iterator >
0033 struct transform_iterator_default_reference
0034 {
0035     using type = decltype(std::declval< UnaryFunc const& >()(std::declval< typename std::iterator_traits< Iterator >::reference >()));
0036 };
0037 
0038 // Compute the iterator_adaptor instantiation to be used for transform_iterator
0039 template< typename UnaryFunc, typename Iterator, typename Reference, typename Value >
0040 struct transform_iterator_base
0041 {
0042 private:
0043     // By default, dereferencing the iterator yields the same as
0044     // the function.
0045     using reference = detail::eval_if_default_t<
0046         Reference,
0047         transform_iterator_default_reference< UnaryFunc, Iterator >
0048     >;
0049 
0050     // To get the default for Value: remove any reference on the
0051     // result type, but retain any constness to signal
0052     // non-writability.  Note that if we adopt Thomas' suggestion
0053     // to key non-writability *only* on the Reference argument,
0054     // we'd need to strip constness here as well.
0055     using cv_value_type = detail::eval_if_default_t<
0056         Value,
0057         std::remove_reference< reference >
0058     >;
0059 
0060  public:
0061     using type = iterator_adaptor<
0062         transform_iterator< UnaryFunc, Iterator, Reference, Value >,
0063         Iterator,
0064         cv_value_type,
0065         use_default,    // Leave the traversal category alone
0066         reference
0067     >;
0068 };
0069 
0070 } // namespace detail
0071 
0072 template< typename UnaryFunc, typename Iterator, typename Reference, typename Value >
0073 class transform_iterator :
0074     public detail::transform_iterator_base< UnaryFunc, Iterator, Reference, Value >::type,
0075     private boost::empty_value< UnaryFunc >
0076 {
0077     friend class iterator_core_access;
0078 
0079 private:
0080     using super_t = typename detail::transform_iterator_base< UnaryFunc, Iterator, Reference, Value >::type;
0081     using functor_base = boost::empty_value< UnaryFunc >;
0082 
0083 public:
0084     transform_iterator() = default;
0085 
0086     transform_iterator(Iterator const& x, UnaryFunc f) :
0087         super_t(x),
0088         functor_base(boost::empty_init_t{}, f)
0089     {}
0090 
0091     // don't provide this constructor if UnaryFunc is a
0092     // function pointer type, since it will be 0.  Too dangerous.
0093     template< bool Requires = std::is_class< UnaryFunc >::value, typename = typename std::enable_if< Requires >::type >
0094     explicit transform_iterator(Iterator const& x) :
0095         super_t(x)
0096     {}
0097 
0098     template<
0099         typename OtherUnaryFunction,
0100         typename OtherIterator,
0101         typename OtherReference,
0102         typename OtherValue,
0103         typename = enable_if_convertible_t< OtherIterator, Iterator >,
0104         typename = enable_if_convertible_t< OtherUnaryFunction, UnaryFunc >
0105     >
0106     transform_iterator(transform_iterator< OtherUnaryFunction, OtherIterator, OtherReference, OtherValue > const& t) :
0107         super_t(t.base()),
0108         functor_base(boost::empty_init_t{}, t.functor())
0109     {}
0110 
0111     UnaryFunc functor() const { return functor_base::get(); }
0112 
0113 private:
0114     typename super_t::reference dereference() const { return functor_base::get()(*this->base()); }
0115 };
0116 
0117 template< typename UnaryFunc, typename Iterator >
0118 inline transform_iterator< UnaryFunc, Iterator > make_transform_iterator(Iterator it, UnaryFunc fun)
0119 {
0120     return transform_iterator< UnaryFunc, Iterator >(it, fun);
0121 }
0122 
0123 // Version which allows explicit specification of the UnaryFunc
0124 // type.
0125 //
0126 // This generator is not provided if UnaryFunc is a function
0127 // pointer type, because it's too dangerous: the default-constructed
0128 // function pointer in the iterator be 0, leading to a runtime
0129 // crash.
0130 template< typename UnaryFunc, typename Iterator >
0131 inline typename std::enable_if<
0132     std::is_class< UnaryFunc >::value,   // We should probably find a cheaper test than is_class<>
0133     transform_iterator< UnaryFunc, Iterator >
0134 >::type make_transform_iterator(Iterator it)
0135 {
0136     return transform_iterator< UnaryFunc, Iterator >(it);
0137 }
0138 
0139 } // namespace iterators
0140 
0141 using iterators::transform_iterator;
0142 using iterators::make_transform_iterator;
0143 
0144 } // namespace boost
0145 
0146 #endif // BOOST_ITERATOR_TRANSFORM_ITERATOR_23022003THW_HPP