epoc32/include/stdapis/boost/iterator/transform_iterator.hpp
author William Roberts <williamr@symbian.org>
Tue, 16 Mar 2010 16:12:26 +0000
branchSymbian2
changeset 2 2fe1408b6811
permissions -rw-r--r--
Final list of Symbian^2 public API header files
williamr@2
     1
// (C) Copyright David Abrahams 2002.
williamr@2
     2
// (C) Copyright Jeremy Siek    2002.
williamr@2
     3
// (C) Copyright Thomas Witt    2002.
williamr@2
     4
// Distributed under the Boost Software License, Version 1.0. (See
williamr@2
     5
// accompanying file LICENSE_1_0.txt or copy at
williamr@2
     6
// http://www.boost.org/LICENSE_1_0.txt)
williamr@2
     7
#ifndef BOOST_TRANSFORM_ITERATOR_23022003THW_HPP
williamr@2
     8
#define BOOST_TRANSFORM_ITERATOR_23022003THW_HPP
williamr@2
     9
williamr@2
    10
#include <boost/function.hpp>
williamr@2
    11
#include <boost/iterator.hpp>
williamr@2
    12
#include <boost/iterator/detail/enable_if.hpp>
williamr@2
    13
#include <boost/iterator/iterator_adaptor.hpp>
williamr@2
    14
#include <boost/iterator/iterator_categories.hpp>
williamr@2
    15
#include <boost/mpl/not.hpp>
williamr@2
    16
#include <boost/mpl/bool.hpp>
williamr@2
    17
#include <boost/type_traits/function_traits.hpp>
williamr@2
    18
#include <boost/type_traits/is_const.hpp>
williamr@2
    19
#include <boost/type_traits/is_class.hpp>
williamr@2
    20
#include <boost/type_traits/is_function.hpp>
williamr@2
    21
#include <boost/type_traits/is_reference.hpp>
williamr@2
    22
#include <boost/type_traits/remove_const.hpp>
williamr@2
    23
#include <boost/type_traits/remove_reference.hpp>
williamr@2
    24
williamr@2
    25
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
williamr@2
    26
# include <boost/type_traits/is_base_and_derived.hpp>
williamr@2
    27
williamr@2
    28
#endif 
williamr@2
    29
#include <boost/iterator/detail/config_def.hpp>
williamr@2
    30
williamr@2
    31
williamr@2
    32
namespace boost
williamr@2
    33
{
williamr@2
    34
  template <class UnaryFunction, class Iterator, class Reference = use_default, class Value = use_default>
williamr@2
    35
  class transform_iterator;
williamr@2
    36
williamr@2
    37
  namespace detail 
williamr@2
    38
  {
williamr@2
    39
williamr@2
    40
    template <class UnaryFunction>
williamr@2
    41
    struct function_object_result
williamr@2
    42
    {
williamr@2
    43
      typedef typename UnaryFunction::result_type type;
williamr@2
    44
    };
williamr@2
    45
williamr@2
    46
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
williamr@2
    47
    template <class Return, class Argument>
williamr@2
    48
    struct function_object_result<Return(*)(Argument)>
williamr@2
    49
    {
williamr@2
    50
      typedef Return type;
williamr@2
    51
    };
williamr@2
    52
#endif
williamr@2
    53
williamr@2
    54
    // Compute the iterator_adaptor instantiation to be used for transform_iterator
williamr@2
    55
    template <class UnaryFunction, class Iterator, class Reference, class Value>
williamr@2
    56
    struct transform_iterator_base
williamr@2
    57
    {
williamr@2
    58
     private:
williamr@2
    59
        // By default, dereferencing the iterator yields the same as
williamr@2
    60
        // the function.  Do we need to adjust the way
williamr@2
    61
        // function_object_result is computed for the standard
williamr@2
    62
        // proposal (e.g. using Doug's result_of)?
williamr@2
    63
        typedef typename ia_dflt_help<
williamr@2
    64
            Reference
williamr@2
    65
          , function_object_result<UnaryFunction>
williamr@2
    66
        >::type reference;
williamr@2
    67
williamr@2
    68
        // To get the default for Value: remove any reference on the
williamr@2
    69
        // result type, but retain any constness to signal
williamr@2
    70
        // non-writability.  Note that if we adopt Thomas' suggestion
williamr@2
    71
        // to key non-writability *only* on the Reference argument,
williamr@2
    72
        // we'd need to strip constness here as well.
williamr@2
    73
        typedef typename ia_dflt_help<
williamr@2
    74
            Value
williamr@2
    75
          , remove_reference<reference>
williamr@2
    76
        >::type cv_value_type;
williamr@2
    77
williamr@2
    78
     public:
williamr@2
    79
        typedef iterator_adaptor<
williamr@2
    80
            transform_iterator<UnaryFunction, Iterator, Reference, Value>
williamr@2
    81
          , Iterator
williamr@2
    82
          , cv_value_type
williamr@2
    83
          , use_default    // Leave the traversal category alone
williamr@2
    84
          , reference
williamr@2
    85
        > type;
williamr@2
    86
    };
williamr@2
    87
  }
williamr@2
    88
williamr@2
    89
  template <class UnaryFunction, class Iterator, class Reference, class Value>
williamr@2
    90
  class transform_iterator
williamr@2
    91
    : public detail::transform_iterator_base<UnaryFunction, Iterator, Reference, Value>::type
williamr@2
    92
  {
williamr@2
    93
    typedef typename
williamr@2
    94
    detail::transform_iterator_base<UnaryFunction, Iterator, Reference, Value>::type
williamr@2
    95
    super_t;
williamr@2
    96
williamr@2
    97
    friend class iterator_core_access;
williamr@2
    98
williamr@2
    99
  public:
williamr@2
   100
    transform_iterator() { }
williamr@2
   101
williamr@2
   102
    transform_iterator(Iterator const& x, UnaryFunction f)
williamr@2
   103
      : super_t(x), m_f(f) { }
williamr@2
   104
williamr@2
   105
    explicit transform_iterator(Iterator const& x)
williamr@2
   106
      : super_t(x)
williamr@2
   107
    {
williamr@2
   108
        // Pro8 is a little too aggressive about instantiating the
williamr@2
   109
        // body of this function.
williamr@2
   110
#if !BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
williamr@2
   111
        // don't provide this constructor if UnaryFunction is a
williamr@2
   112
        // function pointer type, since it will be 0.  Too dangerous.
williamr@2
   113
        BOOST_STATIC_ASSERT(is_class<UnaryFunction>::value);
williamr@2
   114
#endif 
williamr@2
   115
    }
williamr@2
   116
williamr@2
   117
    template<
williamr@2
   118
        class OtherUnaryFunction
williamr@2
   119
      , class OtherIterator
williamr@2
   120
      , class OtherReference
williamr@2
   121
      , class OtherValue>
williamr@2
   122
    transform_iterator(
williamr@2
   123
         transform_iterator<OtherUnaryFunction, OtherIterator, OtherReference, OtherValue> const& t
williamr@2
   124
       , typename enable_if_convertible<OtherIterator, Iterator>::type* = 0
williamr@2
   125
#if !BOOST_WORKAROUND(BOOST_MSVC, == 1310)
williamr@2
   126
       , typename enable_if_convertible<OtherUnaryFunction, UnaryFunction>::type* = 0
williamr@2
   127
#endif 
williamr@2
   128
    )
williamr@2
   129
      : super_t(t.base()), m_f(t.functor())
williamr@2
   130
   {}
williamr@2
   131
williamr@2
   132
    UnaryFunction functor() const
williamr@2
   133
      { return m_f; }
williamr@2
   134
williamr@2
   135
  private:
williamr@2
   136
    typename super_t::reference dereference() const
williamr@2
   137
    { return m_f(*this->base()); }
williamr@2
   138
williamr@2
   139
    // Probably should be the initial base class so it can be
williamr@2
   140
    // optimized away via EBO if it is an empty class.
williamr@2
   141
    UnaryFunction m_f;
williamr@2
   142
  };
williamr@2
   143
williamr@2
   144
  template <class UnaryFunction, class Iterator>
williamr@2
   145
  transform_iterator<UnaryFunction, Iterator>
williamr@2
   146
  make_transform_iterator(Iterator it, UnaryFunction fun)
williamr@2
   147
  {
williamr@2
   148
      return transform_iterator<UnaryFunction, Iterator>(it, fun);
williamr@2
   149
  }
williamr@2
   150
williamr@2
   151
  // Version which allows explicit specification of the UnaryFunction
williamr@2
   152
  // type.
williamr@2
   153
  //
williamr@2
   154
  // This generator is not provided if UnaryFunction is a function
williamr@2
   155
  // pointer type, because it's too dangerous: the default-constructed
williamr@2
   156
  // function pointer in the iterator be 0, leading to a runtime
williamr@2
   157
  // crash.
williamr@2
   158
  template <class UnaryFunction, class Iterator>
williamr@2
   159
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
williamr@2
   160
  typename mpl::if_<
williamr@2
   161
#else 
williamr@2
   162
  typename iterators::enable_if<
williamr@2
   163
#endif 
williamr@2
   164
      is_class<UnaryFunction>   // We should probably find a cheaper test than is_class<>
williamr@2
   165
    , transform_iterator<UnaryFunction, Iterator>
williamr@2
   166
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
williamr@2
   167
    , int[3]
williamr@2
   168
#endif 
williamr@2
   169
  >::type
williamr@2
   170
  make_transform_iterator(Iterator it)
williamr@2
   171
  {
williamr@2
   172
      return transform_iterator<UnaryFunction, Iterator>(it, UnaryFunction());
williamr@2
   173
  }
williamr@2
   174
williamr@2
   175
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
williamr@2
   176
  template <class Return, class Argument, class Iterator>
williamr@2
   177
  transform_iterator< Return (*)(Argument), Iterator, Return>
williamr@2
   178
  make_transform_iterator(Iterator it, Return (*fun)(Argument))
williamr@2
   179
  {
williamr@2
   180
    return transform_iterator<Return (*)(Argument), Iterator, Return>(it, fun);
williamr@2
   181
  }
williamr@2
   182
#endif
williamr@2
   183
williamr@2
   184
} // namespace boost
williamr@2
   185
williamr@2
   186
#include <boost/iterator/detail/config_undef.hpp>
williamr@2
   187
williamr@2
   188
#endif // BOOST_TRANSFORM_ITERATOR_23022003THW_HPP