epoc32/include/stdapis/boost/iterator/iterator_concepts.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 Jeremy Siek 2002.
williamr@2
     2
// Distributed under the Boost Software License, Version 1.0. (See
williamr@2
     3
// accompanying file LICENSE_1_0.txt or copy at
williamr@2
     4
// http://www.boost.org/LICENSE_1_0.txt)
williamr@2
     5
williamr@2
     6
#ifndef BOOST_ITERATOR_CONCEPTS_HPP
williamr@2
     7
#define BOOST_ITERATOR_CONCEPTS_HPP
williamr@2
     8
williamr@2
     9
//  Revision History
williamr@2
    10
//  26 Apr 2003 thw
williamr@2
    11
//       Adapted to new iterator concepts
williamr@2
    12
//  22 Nov 2002 Thomas Witt
williamr@2
    13
//       Added interoperable concept.
williamr@2
    14
williamr@2
    15
#include <boost/concept_check.hpp>
williamr@2
    16
#include <boost/iterator/iterator_categories.hpp>
williamr@2
    17
williamr@2
    18
// Use boost::detail::iterator_traits to work around some MSVC/Dinkumware problems.
williamr@2
    19
#include <boost/detail/iterator.hpp>
williamr@2
    20
williamr@2
    21
#include <boost/type_traits/is_same.hpp>
williamr@2
    22
#include <boost/type_traits/is_integral.hpp>
williamr@2
    23
#include <boost/type_traits/is_convertible.hpp>
williamr@2
    24
williamr@2
    25
#include <boost/mpl/bool.hpp>
williamr@2
    26
#include <boost/mpl/if.hpp>
williamr@2
    27
#include <boost/mpl/and.hpp>
williamr@2
    28
#include <boost/mpl/or.hpp>
williamr@2
    29
williamr@2
    30
#include <boost/static_assert.hpp>
williamr@2
    31
williamr@2
    32
// Use boost/limits to work around missing limits headers on some compilers
williamr@2
    33
#include <boost/limits.hpp>
williamr@2
    34
#include <boost/config.hpp>
williamr@2
    35
williamr@2
    36
#include <algorithm>
williamr@2
    37
williamr@2
    38
namespace boost_concepts {
williamr@2
    39
  // Used a different namespace here (instead of "boost") so that the
williamr@2
    40
  // concept descriptions do not take for granted the names in
williamr@2
    41
  // namespace boost.
williamr@2
    42
williamr@2
    43
  // We use this in place of STATIC_ASSERT((is_convertible<...>))
williamr@2
    44
  // because some compilers (CWPro7.x) can't detect convertibility.
williamr@2
    45
  //
williamr@2
    46
  // Of course, that just gets us a different error at the moment with
williamr@2
    47
  // some tests, since new iterator category deduction still depends
williamr@2
    48
  // on convertibility detection. We might need some specializations
williamr@2
    49
  // to support this compiler.
williamr@2
    50
  template <class Target, class Source>
williamr@2
    51
  struct static_assert_base_and_derived
williamr@2
    52
  {
williamr@2
    53
      static_assert_base_and_derived(Target* = (Source*)0) {}
williamr@2
    54
  };
williamr@2
    55
williamr@2
    56
  //===========================================================================
williamr@2
    57
  // Iterator Access Concepts
williamr@2
    58
williamr@2
    59
  template <typename Iterator>
williamr@2
    60
  class ReadableIteratorConcept {
williamr@2
    61
  public:
williamr@2
    62
    typedef BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<Iterator>::value_type value_type;
williamr@2
    63
williamr@2
    64
    void constraints() {
williamr@2
    65
      boost::function_requires< boost::AssignableConcept<Iterator> >();
williamr@2
    66
      boost::function_requires< boost::CopyConstructibleConcept<Iterator> >();
williamr@2
    67
williamr@2
    68
      value_type v = *i;
williamr@2
    69
      boost::ignore_unused_variable_warning(v);
williamr@2
    70
    }
williamr@2
    71
    Iterator i;
williamr@2
    72
  };
williamr@2
    73
  
williamr@2
    74
  template <
williamr@2
    75
      typename Iterator
williamr@2
    76
    , typename ValueType = BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<Iterator>::value_type
williamr@2
    77
  >
williamr@2
    78
  class WritableIteratorConcept {
williamr@2
    79
  public:
williamr@2
    80
      
williamr@2
    81
    void constraints() {
williamr@2
    82
      boost::function_requires< boost::CopyConstructibleConcept<Iterator> >();
williamr@2
    83
      *i = v;
williamr@2
    84
    }
williamr@2
    85
    ValueType v;
williamr@2
    86
    Iterator i;
williamr@2
    87
  };
williamr@2
    88
  
williamr@2
    89
  template <typename Iterator>
williamr@2
    90
  class SwappableIteratorConcept {
williamr@2
    91
  public:
williamr@2
    92
williamr@2
    93
    void constraints() {
williamr@2
    94
      std::iter_swap(i1, i2);
williamr@2
    95
    }
williamr@2
    96
    Iterator i1;
williamr@2
    97
    Iterator i2;
williamr@2
    98
  };
williamr@2
    99
williamr@2
   100
  template <typename Iterator>
williamr@2
   101
  class LvalueIteratorConcept
williamr@2
   102
  {
williamr@2
   103
   public:
williamr@2
   104
      typedef typename boost::detail::iterator_traits<Iterator>::value_type value_type;
williamr@2
   105
      void constraints()
williamr@2
   106
      {
williamr@2
   107
        value_type& r = const_cast<value_type&>(*i);
williamr@2
   108
        boost::ignore_unused_variable_warning(r);
williamr@2
   109
      }
williamr@2
   110
    Iterator i;
williamr@2
   111
  };
williamr@2
   112
williamr@2
   113
  
williamr@2
   114
  //===========================================================================
williamr@2
   115
  // Iterator Traversal Concepts
williamr@2
   116
williamr@2
   117
  template <typename Iterator>
williamr@2
   118
  class IncrementableIteratorConcept {
williamr@2
   119
  public:
williamr@2
   120
    typedef typename boost::iterator_traversal<Iterator>::type traversal_category;
williamr@2
   121
williamr@2
   122
    void constraints() {
williamr@2
   123
      boost::function_requires< boost::AssignableConcept<Iterator> >();
williamr@2
   124
      boost::function_requires< boost::CopyConstructibleConcept<Iterator> >();
williamr@2
   125
williamr@2
   126
      BOOST_STATIC_ASSERT(
williamr@2
   127
          (boost::is_convertible<
williamr@2
   128
                traversal_category
williamr@2
   129
              , boost::incrementable_traversal_tag
williamr@2
   130
           >::value
williamr@2
   131
          ));
williamr@2
   132
williamr@2
   133
      ++i;
williamr@2
   134
      (void)i++;
williamr@2
   135
    }
williamr@2
   136
    Iterator i;
williamr@2
   137
  };
williamr@2
   138
williamr@2
   139
  template <typename Iterator>
williamr@2
   140
  class SinglePassIteratorConcept {
williamr@2
   141
  public:
williamr@2
   142
    typedef typename boost::iterator_traversal<Iterator>::type traversal_category;
williamr@2
   143
    typedef typename boost::detail::iterator_traits<Iterator>::difference_type difference_type;
williamr@2
   144
williamr@2
   145
    void constraints() {
williamr@2
   146
      boost::function_requires< IncrementableIteratorConcept<Iterator> >();
williamr@2
   147
      boost::function_requires< boost::EqualityComparableConcept<Iterator> >();
williamr@2
   148
williamr@2
   149
      BOOST_STATIC_ASSERT(
williamr@2
   150
          (boost::is_convertible<
williamr@2
   151
                traversal_category
williamr@2
   152
              , boost::single_pass_traversal_tag
williamr@2
   153
           >::value
williamr@2
   154
          ));
williamr@2
   155
    }
williamr@2
   156
  };
williamr@2
   157
williamr@2
   158
  template <typename Iterator>
williamr@2
   159
  class ForwardTraversalConcept {
williamr@2
   160
  public:
williamr@2
   161
    typedef typename boost::iterator_traversal<Iterator>::type traversal_category;
williamr@2
   162
    typedef typename boost::detail::iterator_traits<Iterator>::difference_type difference_type;
williamr@2
   163
williamr@2
   164
    void constraints() {
williamr@2
   165
      boost::function_requires< SinglePassIteratorConcept<Iterator> >();
williamr@2
   166
      boost::function_requires< 
williamr@2
   167
        boost::DefaultConstructibleConcept<Iterator> >();
williamr@2
   168
williamr@2
   169
      typedef boost::mpl::and_<
williamr@2
   170
        boost::is_integral<difference_type>,
williamr@2
   171
        boost::mpl::bool_< std::numeric_limits<difference_type>::is_signed >
williamr@2
   172
        > difference_type_is_signed_integral;
williamr@2
   173
williamr@2
   174
      BOOST_STATIC_ASSERT(difference_type_is_signed_integral::value);
williamr@2
   175
      BOOST_STATIC_ASSERT(
williamr@2
   176
          (boost::is_convertible<
williamr@2
   177
                traversal_category
williamr@2
   178
              , boost::forward_traversal_tag
williamr@2
   179
           >::value
williamr@2
   180
          ));
williamr@2
   181
    }
williamr@2
   182
  };
williamr@2
   183
  
williamr@2
   184
  template <typename Iterator>
williamr@2
   185
  class BidirectionalTraversalConcept {
williamr@2
   186
  public:
williamr@2
   187
    typedef typename boost::iterator_traversal<Iterator>::type traversal_category;
williamr@2
   188
williamr@2
   189
    void constraints() {
williamr@2
   190
      boost::function_requires< ForwardTraversalConcept<Iterator> >();
williamr@2
   191
      
williamr@2
   192
      BOOST_STATIC_ASSERT(
williamr@2
   193
          (boost::is_convertible<
williamr@2
   194
                traversal_category
williamr@2
   195
              , boost::bidirectional_traversal_tag
williamr@2
   196
           >::value
williamr@2
   197
          ));
williamr@2
   198
williamr@2
   199
      --i;
williamr@2
   200
      (void)i--;
williamr@2
   201
    }
williamr@2
   202
    Iterator i;
williamr@2
   203
  };
williamr@2
   204
williamr@2
   205
  template <typename Iterator>
williamr@2
   206
  class RandomAccessTraversalConcept {
williamr@2
   207
  public:
williamr@2
   208
    typedef typename boost::iterator_traversal<Iterator>::type traversal_category;
williamr@2
   209
    typedef typename boost::detail::iterator_traits<Iterator>::difference_type
williamr@2
   210
      difference_type;
williamr@2
   211
williamr@2
   212
    void constraints() {
williamr@2
   213
      boost::function_requires< BidirectionalTraversalConcept<Iterator> >();
williamr@2
   214
williamr@2
   215
      BOOST_STATIC_ASSERT(
williamr@2
   216
          (boost::is_convertible<
williamr@2
   217
                traversal_category
williamr@2
   218
              , boost::random_access_traversal_tag
williamr@2
   219
           >::value
williamr@2
   220
          ));
williamr@2
   221
      
williamr@2
   222
      i += n;
williamr@2
   223
      i = i + n;
williamr@2
   224
      i = n + i;
williamr@2
   225
      i -= n;
williamr@2
   226
      i = i - n;
williamr@2
   227
      n = i - j;
williamr@2
   228
    }
williamr@2
   229
    difference_type n;
williamr@2
   230
    Iterator i, j;
williamr@2
   231
  };
williamr@2
   232
williamr@2
   233
  //===========================================================================
williamr@2
   234
  // Iterator Interoperability Concept
williamr@2
   235
williamr@2
   236
  namespace detail
williamr@2
   237
  {
williamr@2
   238
williamr@2
   239
    template <typename Iterator1, typename Iterator2>
williamr@2
   240
    void interop_single_pass_constraints(Iterator1 const& i1, Iterator2 const& i2)
williamr@2
   241
    {
williamr@2
   242
      bool b;
williamr@2
   243
      b = i1 == i2;
williamr@2
   244
      b = i1 != i2;
williamr@2
   245
      
williamr@2
   246
      b = i2 == i1;
williamr@2
   247
      b = i2 != i1;
williamr@2
   248
    }
williamr@2
   249
    
williamr@2
   250
    template <typename Iterator1, typename Iterator2>
williamr@2
   251
    void interop_rand_access_constraints(Iterator1 const& i1, Iterator2 const& i2,
williamr@2
   252
                                         boost::random_access_traversal_tag, boost::random_access_traversal_tag)
williamr@2
   253
    {
williamr@2
   254
      bool b;
williamr@2
   255
      typename boost::detail::iterator_traits<Iterator2>::difference_type n;
williamr@2
   256
      b = i1 <  i2;
williamr@2
   257
      b = i1 <= i2;
williamr@2
   258
      b = i1 >  i2;
williamr@2
   259
      b = i1 >= i2;
williamr@2
   260
      n = i1 -  i2;
williamr@2
   261
      
williamr@2
   262
      b = i2 <  i1;
williamr@2
   263
      b = i2 <= i1;
williamr@2
   264
      b = i2 >  i1;
williamr@2
   265
      b = i2 >= i1;
williamr@2
   266
      n = i2 -  i1;
williamr@2
   267
    }
williamr@2
   268
    template <typename Iterator1, typename Iterator2>
williamr@2
   269
    void interop_rand_access_constraints(Iterator1 const& i1, Iterator2 const& i2,
williamr@2
   270
                                         boost::single_pass_traversal_tag, boost::single_pass_traversal_tag)
williamr@2
   271
    { }
williamr@2
   272
williamr@2
   273
  } // namespace detail
williamr@2
   274
williamr@2
   275
  template <typename Iterator, typename ConstIterator>
williamr@2
   276
  class InteroperableIteratorConcept
williamr@2
   277
  {
williamr@2
   278
  public:
williamr@2
   279
      typedef typename boost::detail::pure_traversal_tag<
williamr@2
   280
          typename boost::iterator_traversal<
williamr@2
   281
              Iterator
williamr@2
   282
          >::type
williamr@2
   283
      >::type traversal_category;
williamr@2
   284
williamr@2
   285
      typedef typename boost::detail::pure_traversal_tag<
williamr@2
   286
          typename boost::iterator_traversal<
williamr@2
   287
              ConstIterator
williamr@2
   288
          >::type
williamr@2
   289
      >::type const_traversal_category;
williamr@2
   290
williamr@2
   291
      void constraints()
williamr@2
   292
      {
williamr@2
   293
          boost::function_requires< SinglePassIteratorConcept<Iterator> >();
williamr@2
   294
          boost::function_requires< SinglePassIteratorConcept<ConstIterator> >();
williamr@2
   295
williamr@2
   296
          detail::interop_single_pass_constraints(i, ci);
williamr@2
   297
          detail::interop_rand_access_constraints(i, ci, traversal_category(), const_traversal_category());
williamr@2
   298
williamr@2
   299
          ci = i;
williamr@2
   300
      }
williamr@2
   301
      Iterator      i;
williamr@2
   302
      ConstIterator ci;
williamr@2
   303
  };
williamr@2
   304
williamr@2
   305
} // namespace boost_concepts
williamr@2
   306
williamr@2
   307
williamr@2
   308
#endif // BOOST_ITERATOR_CONCEPTS_HPP