Statistics
| Revision:

root / tmp / org.txm.statsengine.r.core.win32 / res / win32 / library / BH / include / boost / algorithm / clamp.hpp @ 2486

History | View | Annotate | Download (7.5 kB)

1
/* 
2
   Copyright (c) Marshall Clow 2008-2012.
3

4
   Distributed under the Boost Software License, Version 1.0. (See accompanying
5
   file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6

7
 Revision history:
8
   27 June 2009 mtc First version
9
   23 Oct  2010 mtc Added predicate version
10
   
11
*/
12

    
13
/// \file clamp.hpp
14
/// \brief Clamp algorithm
15
/// \author Marshall Clow
16
///
17
/// Suggested by olafvdspek in https://svn.boost.org/trac/boost/ticket/3215
18

    
19
#ifndef BOOST_ALGORITHM_CLAMP_HPP
20
#define BOOST_ALGORITHM_CLAMP_HPP
21

    
22
#include <functional>       //  For std::less
23
#include <iterator>         //  For std::iterator_traits
24
#include <cassert>
25

    
26
#include <boost/range/begin.hpp>
27
#include <boost/range/end.hpp>
28
#include <boost/mpl/identity.hpp>      // for identity
29
#include <boost/utility/enable_if.hpp> // for boost::disable_if
30

    
31
namespace boost { namespace algorithm {
32

    
33
/// \fn clamp ( T const& val, 
34
///               typename boost::mpl::identity<T>::type const & lo, 
35
///               typename boost::mpl::identity<T>::type const & hi, Pred p )
36
/// \return the value "val" brought into the range [ lo, hi ]
37
///     using the comparison predicate p.
38
///     If p ( val, lo ) return lo.
39
///     If p ( hi, val ) return hi.
40
///     Otherwise, return the original value.
41
/// 
42
/// \param val   The value to be clamped
43
/// \param lo    The lower bound of the range to be clamped to
44
/// \param hi    The upper bound of the range to be clamped to
45
/// \param p     A predicate to use to compare the values.
46
///                 p ( a, b ) returns a boolean.
47
///
48
  template<typename T, typename Pred> 
49
  T const & clamp ( T const& val, 
50
    typename boost::mpl::identity<T>::type const & lo, 
51
    typename boost::mpl::identity<T>::type const & hi, Pred p )
52
  {
53
//    assert ( !p ( hi, lo ));    // Can't assert p ( lo, hi ) b/c they might be equal
54
    return p ( val, lo ) ? lo : p ( hi, val ) ? hi : val;
55
  } 
56

    
57

    
58
/// \fn clamp ( T const& val, 
59
///               typename boost::mpl::identity<T>::type const & lo, 
60
///               typename boost::mpl::identity<T>::type const & hi )
61
/// \return the value "val" brought into the range [ lo, hi ].
62
///     If the value is less than lo, return lo.
63
///     If the value is greater than "hi", return hi.
64
///     Otherwise, return the original value.
65
///
66
/// \param val   The value to be clamped
67
/// \param lo    The lower bound of the range to be clamped to
68
/// \param hi    The upper bound of the range to be clamped to
69
///
70
  template<typename T> 
71
  T const& clamp ( const T& val, 
72
    typename boost::mpl::identity<T>::type const & lo, 
73
    typename boost::mpl::identity<T>::type const & hi )
74
  {
75
    return (clamp) ( val, lo, hi, std::less<T>());
76
  } 
77

    
78
/// \fn clamp_range ( InputIterator first, InputIterator last, OutputIterator out, 
79
///       std::iterator_traits<InputIterator>::value_type const & lo, 
80
///       std::iterator_traits<InputIterator>::value_type const & hi )
81
/// \return clamp the sequence of values [first, last) into [ lo, hi ]
82
/// 
83
/// \param first The start of the range of values
84
/// \param last  One past the end of the range of input values
85
/// \param out   An output iterator to write the clamped values into
86
/// \param lo    The lower bound of the range to be clamped to
87
/// \param hi    The upper bound of the range to be clamped to
88
///
89
  template<typename InputIterator, typename OutputIterator> 
90
  OutputIterator clamp_range ( InputIterator first, InputIterator last, OutputIterator out,
91
    typename std::iterator_traits<InputIterator>::value_type const & lo, 
92
    typename std::iterator_traits<InputIterator>::value_type const & hi )
93
  {
94
  // this could also be written with bind and std::transform
95
    while ( first != last )
96
        *out++ = clamp ( *first++, lo, hi );
97
    return out;
98
  } 
99

    
100
/// \fn clamp_range ( const Range &r, OutputIterator out, 
101
///       typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type const & lo,
102
///       typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type const & hi )
103
/// \return clamp the sequence of values [first, last) into [ lo, hi ]
104
/// 
105
/// \param r     The range of values to be clamped
106
/// \param out   An output iterator to write the clamped values into
107
/// \param lo    The lower bound of the range to be clamped to
108
/// \param hi    The upper bound of the range to be clamped to
109
///
110
  template<typename Range, typename OutputIterator> 
111
  typename boost::disable_if_c<boost::is_same<Range, OutputIterator>::value, OutputIterator>::type
112
  clamp_range ( const Range &r, OutputIterator out,
113
    typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type const & lo, 
114
    typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type const & hi )
115
  {
116
    return clamp_range ( boost::begin ( r ), boost::end ( r ), out, lo, hi );
117
  } 
118

    
119

    
120
/// \fn clamp_range ( InputIterator first, InputIterator last, OutputIterator out, 
121
///       std::iterator_traits<InputIterator>::value_type const & lo, 
122
///       std::iterator_traits<InputIterator>::value_type const & hi, Pred p )
123
/// \return clamp the sequence of values [first, last) into [ lo, hi ]
124
///     using the comparison predicate p.
125
/// 
126
/// \param first The start of the range of values
127
/// \param last  One past the end of the range of input values
128
/// \param out   An output iterator to write the clamped values into
129
/// \param lo    The lower bound of the range to be clamped to
130
/// \param hi    The upper bound of the range to be clamped to
131
/// \param p     A predicate to use to compare the values.
132
///                 p ( a, b ) returns a boolean.
133

    
134
///
135
  template<typename InputIterator, typename OutputIterator, typename Pred> 
136
  OutputIterator clamp_range ( InputIterator first, InputIterator last, OutputIterator out,
137
    typename std::iterator_traits<InputIterator>::value_type const & lo, 
138
    typename std::iterator_traits<InputIterator>::value_type const & hi, Pred p )
139
  {
140
  // this could also be written with bind and std::transform
141
    while ( first != last )
142
        *out++ = clamp ( *first++, lo, hi, p );
143
    return out;
144
  } 
145

    
146
/// \fn clamp_range ( const Range &r, OutputIterator out, 
147
///       typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type const & lo,
148
///       typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type const & hi,
149
///       Pred p )
150
/// \return clamp the sequence of values [first, last) into [ lo, hi ]
151
///     using the comparison predicate p.
152
/// 
153
/// \param r     The range of values to be clamped
154
/// \param out   An output iterator to write the clamped values into
155
/// \param lo    The lower bound of the range to be clamped to
156
/// \param hi    The upper bound of the range to be clamped to
157
/// \param p     A predicate to use to compare the values.
158
///                 p ( a, b ) returns a boolean.
159
//
160
//  Disable this template if the first two parameters are the same type;
161
//  In that case, the user will get the two iterator version.
162
  template<typename Range, typename OutputIterator, typename Pred> 
163
  typename boost::disable_if_c<boost::is_same<Range, OutputIterator>::value, OutputIterator>::type
164
  clamp_range ( const Range &r, OutputIterator out,
165
    typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type const & lo, 
166
    typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type const & hi,
167
    Pred p )
168
  {
169
    return clamp_range ( boost::begin ( r ), boost::end ( r ), out, lo, hi, p );
170
  } 
171

    
172

    
173
}}
174

    
175
#endif // BOOST_ALGORITHM_CLAMP_HPP