| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- // (C) Copyright David Abrahams 2002.
- // (C) Copyright Jeremy Siek 2002.
- // (C) Copyright Thomas Witt 2002.
- // Distributed under the Boost Software License, Version 1.0. (See
- // accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt)
- #ifndef BOOST_ITERATOR_TRANSFORM_ITERATOR_23022003THW_HPP
- #define BOOST_ITERATOR_TRANSFORM_ITERATOR_23022003THW_HPP
- #include <iterator>
- #include <type_traits>
- #include <boost/core/use_default.hpp>
- #include <boost/core/empty_value.hpp>
- #include <boost/iterator/iterator_adaptor.hpp>
- #include <boost/iterator/enable_if_convertible.hpp>
- #include <boost/iterator/detail/eval_if_default.hpp>
- namespace boost {
- namespace iterators {
- template<
- typename UnaryFunction,
- typename Iterator,
- typename Reference = use_default,
- typename Value = use_default
- >
- class transform_iterator;
- namespace detail {
- template< typename UnaryFunc, typename Iterator >
- struct transform_iterator_default_reference
- {
- using type = decltype(std::declval< UnaryFunc const& >()(std::declval< typename std::iterator_traits< Iterator >::reference >()));
- };
- // Compute the iterator_adaptor instantiation to be used for transform_iterator
- template< typename UnaryFunc, typename Iterator, typename Reference, typename Value >
- struct transform_iterator_base
- {
- private:
- // By default, dereferencing the iterator yields the same as
- // the function.
- using reference = detail::eval_if_default_t<
- Reference,
- transform_iterator_default_reference< UnaryFunc, Iterator >
- >;
- // To get the default for Value: remove any reference on the
- // result type, but retain any constness to signal
- // non-writability. Note that if we adopt Thomas' suggestion
- // to key non-writability *only* on the Reference argument,
- // we'd need to strip constness here as well.
- using cv_value_type = detail::eval_if_default_t<
- Value,
- std::remove_reference< reference >
- >;
- public:
- using type = iterator_adaptor<
- transform_iterator< UnaryFunc, Iterator, Reference, Value >,
- Iterator,
- cv_value_type,
- use_default, // Leave the traversal category alone
- reference
- >;
- };
- } // namespace detail
- template< typename UnaryFunc, typename Iterator, typename Reference, typename Value >
- class transform_iterator :
- public detail::transform_iterator_base< UnaryFunc, Iterator, Reference, Value >::type,
- private boost::empty_value< UnaryFunc >
- {
- friend class iterator_core_access;
- private:
- using super_t = typename detail::transform_iterator_base< UnaryFunc, Iterator, Reference, Value >::type;
- using functor_base = boost::empty_value< UnaryFunc >;
- public:
- transform_iterator() = default;
- transform_iterator(Iterator const& x, UnaryFunc f) :
- super_t(x),
- functor_base(boost::empty_init_t{}, f)
- {}
- // don't provide this constructor if UnaryFunc is a
- // function pointer type, since it will be 0. Too dangerous.
- template< bool Requires = std::is_class< UnaryFunc >::value, typename = typename std::enable_if< Requires >::type >
- explicit transform_iterator(Iterator const& x) :
- super_t(x)
- {}
- template<
- typename OtherUnaryFunction,
- typename OtherIterator,
- typename OtherReference,
- typename OtherValue,
- typename = enable_if_convertible_t< OtherIterator, Iterator >,
- typename = enable_if_convertible_t< OtherUnaryFunction, UnaryFunc >
- >
- transform_iterator(transform_iterator< OtherUnaryFunction, OtherIterator, OtherReference, OtherValue > const& t) :
- super_t(t.base()),
- functor_base(boost::empty_init_t{}, t.functor())
- {}
- UnaryFunc functor() const { return functor_base::get(); }
- private:
- typename super_t::reference dereference() const { return functor_base::get()(*this->base()); }
- };
- template< typename UnaryFunc, typename Iterator >
- inline transform_iterator< UnaryFunc, Iterator > make_transform_iterator(Iterator it, UnaryFunc fun)
- {
- return transform_iterator< UnaryFunc, Iterator >(it, fun);
- }
- // Version which allows explicit specification of the UnaryFunc
- // type.
- //
- // This generator is not provided if UnaryFunc is a function
- // pointer type, because it's too dangerous: the default-constructed
- // function pointer in the iterator be 0, leading to a runtime
- // crash.
- template< typename UnaryFunc, typename Iterator >
- inline typename std::enable_if<
- std::is_class< UnaryFunc >::value, // We should probably find a cheaper test than is_class<>
- transform_iterator< UnaryFunc, Iterator >
- >::type make_transform_iterator(Iterator it)
- {
- return transform_iterator< UnaryFunc, Iterator >(it);
- }
- } // namespace iterators
- using iterators::transform_iterator;
- using iterators::make_transform_iterator;
- } // namespace boost
- #endif // BOOST_ITERATOR_TRANSFORM_ITERATOR_23022003THW_HPP
|