Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-11-15 09:34:15

0001 //  Boost next_prior.hpp header file  ---------------------------------------//
0002 
0003 //  (C) Copyright Dave Abrahams and Daniel Walker 1999-2003.
0004 //  Copyright (c) Andrey Semashev 2017
0005 //
0006 //  Distributed under the Boost Software License, Version 1.0.
0007 //  (See accompanying file LICENSE_1_0.txt or copy at
0008 //  http://www.boost.org/LICENSE_1_0.txt)
0009 
0010 //  See http://www.boost.org/libs/utility for documentation.
0011 
0012 //  Revision History
0013 //  13 Dec 2003  Added next(x, n) and prior(x, n) (Daniel Walker)
0014 
0015 #ifndef BOOST_NEXT_PRIOR_HPP_INCLUDED
0016 #define BOOST_NEXT_PRIOR_HPP_INCLUDED
0017 
0018 #include <boost/config.hpp>
0019 #include <boost/type_traits/has_plus.hpp>
0020 #include <boost/type_traits/has_plus_assign.hpp>
0021 #include <boost/type_traits/has_minus.hpp>
0022 #include <boost/type_traits/has_minus_assign.hpp>
0023 #include <boost/iterator/is_iterator.hpp>
0024 #include <boost/iterator/advance.hpp>
0025 #include <boost/iterator/reverse_iterator.hpp>
0026 
0027 namespace boost {
0028 
0029 //  Helper functions for classes like bidirectional iterators not supporting
0030 //  operator+ and operator-
0031 //
0032 //  Usage:
0033 //    const std::list<T>::iterator p = get_some_iterator();
0034 //    const std::list<T>::iterator prev = boost::prior(p);
0035 //    const std::list<T>::iterator next = boost::next(prev, 2);
0036 
0037 //  Contributed by Dave Abrahams
0038 
0039 namespace next_prior_detail {
0040 
0041 template< typename T, typename Distance, bool HasPlus = has_plus< T, Distance >::value >
0042 struct next_plus_impl;
0043 
0044 template< typename T, typename Distance >
0045 struct next_plus_impl< T, Distance, true >
0046 {
0047     static T call(T x, Distance n)
0048     {
0049         return x + n;
0050     }
0051 };
0052 
0053 template< typename T, typename Distance, bool HasPlusAssign = has_plus_assign< T, Distance >::value >
0054 struct next_plus_assign_impl :
0055     public next_plus_impl< T, Distance >
0056 {
0057 };
0058 
0059 template< typename T, typename Distance >
0060 struct next_plus_assign_impl< T, Distance, true >
0061 {
0062     static T call(T x, Distance n)
0063     {
0064         x += n;
0065         return x;
0066     }
0067 };
0068 
0069 template< typename T, typename Distance, bool IsIterator = boost::iterators::is_iterator< T >::value >
0070 struct next_advance_impl :
0071     public next_plus_assign_impl< T, Distance >
0072 {
0073 };
0074 
0075 template< typename T, typename Distance >
0076 struct next_advance_impl< T, Distance, true >
0077 {
0078     static T call(T x, Distance n)
0079     {
0080         boost::iterators::advance(x, n);
0081         return x;
0082     }
0083 };
0084 
0085 
0086 template< typename T, typename Distance, bool HasMinus = has_minus< T, Distance >::value >
0087 struct prior_minus_impl;
0088 
0089 template< typename T, typename Distance >
0090 struct prior_minus_impl< T, Distance, true >
0091 {
0092     static T call(T x, Distance n)
0093     {
0094         return x - n;
0095     }
0096 };
0097 
0098 template< typename T, typename Distance, bool HasMinusAssign = has_minus_assign< T, Distance >::value >
0099 struct prior_minus_assign_impl :
0100     public prior_minus_impl< T, Distance >
0101 {
0102 };
0103 
0104 template< typename T, typename Distance >
0105 struct prior_minus_assign_impl< T, Distance, true >
0106 {
0107     static T call(T x, Distance n)
0108     {
0109         x -= n;
0110         return x;
0111     }
0112 };
0113 
0114 template< typename T, typename Distance, bool IsIterator = boost::iterators::is_iterator< T >::value >
0115 struct prior_advance_impl :
0116     public prior_minus_assign_impl< T, Distance >
0117 {
0118 };
0119 
0120 template< typename T, typename Distance >
0121 struct prior_advance_impl< T, Distance, true >
0122 {
0123     static T call(T x, Distance n)
0124     {
0125         // Avoid negating n to sidestep possible integer overflow
0126         boost::iterators::reverse_iterator< T > rx(x);
0127         boost::iterators::advance(rx, n);
0128         return rx.base();
0129     }
0130 };
0131 
0132 } // namespace next_prior_detail
0133 
0134 template <class T>
0135 inline T next(T x) { return ++x; }
0136 
0137 template <class T, class Distance>
0138 inline T next(T x, Distance n)
0139 {
0140     return next_prior_detail::next_advance_impl< T, Distance >::call(x, n);
0141 }
0142 
0143 template <class T>
0144 inline T prior(T x) { return --x; }
0145 
0146 template <class T, class Distance>
0147 inline T prior(T x, Distance n)
0148 {
0149     return next_prior_detail::prior_advance_impl< T, Distance >::call(x, n);
0150 }
0151 
0152 } // namespace boost
0153 
0154 #endif  // BOOST_NEXT_PRIOR_HPP_INCLUDED