Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:28:25

0001 /* 
0002    Copyright (c) Marshall Clow 2008-2012.
0003 
0004    Distributed under the Boost Software License, Version 1.0. (See accompanying
0005    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 
0007  Revision history:
0008    27 June 2009 mtc First version
0009    23 Oct  2010 mtc Added predicate version
0010    
0011 */
0012 
0013 /// \file clamp.hpp
0014 /// \brief Clamp algorithm
0015 /// \author Marshall Clow
0016 ///
0017 /// Suggested by olafvdspek in https://svn.boost.org/trac/boost/ticket/3215
0018 
0019 #ifndef BOOST_ALGORITHM_CLAMP_HPP
0020 #define BOOST_ALGORITHM_CLAMP_HPP
0021 
0022 #include <functional>       //  For std::less
0023 #include <iterator>         //  For std::iterator_traits
0024 #include <cassert>
0025 
0026 #include <boost/config.hpp>
0027 #include <boost/range/begin.hpp>
0028 #include <boost/range/end.hpp>
0029 #include <boost/type_traits/type_identity.hpp> // for boost::type_identity
0030 #include <boost/core/enable_if.hpp>            // for boost::disable_if
0031 
0032 namespace boost { namespace algorithm {
0033 
0034 /// \fn clamp ( T const& val, 
0035 ///               typename boost::type_identity<T>::type const & lo, 
0036 ///               typename boost::type_identity<T>::type const & hi, Pred p )
0037 /// \return the value "val" brought into the range [ lo, hi ]
0038 ///     using the comparison predicate p.
0039 ///     If p ( val, lo ) return lo.
0040 ///     If p ( hi, val ) return hi.
0041 ///     Otherwise, return the original value.
0042 /// 
0043 /// \param val   The value to be clamped
0044 /// \param lo    The lower bound of the range to be clamped to
0045 /// \param hi    The upper bound of the range to be clamped to
0046 /// \param p     A predicate to use to compare the values.
0047 ///                 p ( a, b ) returns a boolean.
0048 ///
0049   template<typename T, typename Pred> 
0050   BOOST_CXX14_CONSTEXPR T const & clamp ( T const& val, 
0051     typename boost::type_identity<T>::type const & lo, 
0052     typename boost::type_identity<T>::type const & hi, Pred p )
0053   {
0054 //    assert ( !p ( hi, lo ));    // Can't assert p ( lo, hi ) b/c they might be equal
0055     return p ( val, lo ) ? lo : p ( hi, val ) ? hi : val;
0056   } 
0057 
0058 
0059 /// \fn clamp ( T const& val, 
0060 ///               typename boost::identity<T>::type const & lo, 
0061 ///               typename boost::identity<T>::type const & hi )
0062 /// \return the value "val" brought into the range [ lo, hi ].
0063 ///     If the value is less than lo, return lo.
0064 ///     If the value is greater than "hi", return hi.
0065 ///     Otherwise, return the original value.
0066 ///
0067 /// \param val   The value to be clamped
0068 /// \param lo    The lower bound of the range to be clamped to
0069 /// \param hi    The upper bound of the range to be clamped to
0070 ///
0071   template<typename T> 
0072   BOOST_CXX14_CONSTEXPR T const& clamp ( const T& val, 
0073     typename boost::type_identity<T>::type const & lo, 
0074     typename boost::type_identity<T>::type const & hi )
0075   {
0076     return boost::algorithm::clamp ( val, lo, hi, std::less<T>());
0077   } 
0078 
0079 /// \fn clamp_range ( InputIterator first, InputIterator last, OutputIterator out, 
0080 ///       std::iterator_traits<InputIterator>::value_type const & lo, 
0081 ///       std::iterator_traits<InputIterator>::value_type const & hi )
0082 /// \return clamp the sequence of values [first, last) into [ lo, hi ]
0083 /// 
0084 /// \param first The start of the range of values
0085 /// \param last  One past the end of the range of input values
0086 /// \param out   An output iterator to write the clamped values into
0087 /// \param lo    The lower bound of the range to be clamped to
0088 /// \param hi    The upper bound of the range to be clamped to
0089 ///
0090   template<typename InputIterator, typename OutputIterator> 
0091   BOOST_CXX14_CONSTEXPR OutputIterator clamp_range ( InputIterator first, InputIterator last, OutputIterator out,
0092     typename std::iterator_traits<InputIterator>::value_type const & lo, 
0093     typename std::iterator_traits<InputIterator>::value_type const & hi )
0094   {
0095   // this could also be written with bind and std::transform
0096     while ( first != last )
0097         *out++ = boost::algorithm::clamp ( *first++, lo, hi );
0098     return out;
0099   } 
0100 
0101 /// \fn clamp_range ( const Range &r, OutputIterator out, 
0102 ///       typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type const & lo,
0103 ///       typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type const & hi )
0104 /// \return clamp the sequence of values [first, last) into [ lo, hi ]
0105 /// 
0106 /// \param r     The range of values to be clamped
0107 /// \param out   An output iterator to write the clamped values into
0108 /// \param lo    The lower bound of the range to be clamped to
0109 /// \param hi    The upper bound of the range to be clamped to
0110 ///
0111   template<typename Range, typename OutputIterator> 
0112   BOOST_CXX14_CONSTEXPR typename boost::disable_if_c<boost::is_same<Range, OutputIterator>::value, OutputIterator>::type
0113   clamp_range ( const Range &r, OutputIterator out,
0114     typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type const & lo, 
0115     typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type const & hi )
0116   {
0117     return boost::algorithm::clamp_range ( boost::begin ( r ), boost::end ( r ), out, lo, hi );
0118   } 
0119 
0120 
0121 /// \fn clamp_range ( InputIterator first, InputIterator last, OutputIterator out, 
0122 ///       std::iterator_traits<InputIterator>::value_type const & lo, 
0123 ///       std::iterator_traits<InputIterator>::value_type const & hi, Pred p )
0124 /// \return clamp the sequence of values [first, last) into [ lo, hi ]
0125 ///     using the comparison predicate p.
0126 /// 
0127 /// \param first The start of the range of values
0128 /// \param last  One past the end of the range of input values
0129 /// \param out   An output iterator to write the clamped values into
0130 /// \param lo    The lower bound of the range to be clamped to
0131 /// \param hi    The upper bound of the range to be clamped to
0132 /// \param p     A predicate to use to compare the values.
0133 ///                 p ( a, b ) returns a boolean.
0134 
0135 ///
0136   template<typename InputIterator, typename OutputIterator, typename Pred> 
0137   BOOST_CXX14_CONSTEXPR OutputIterator clamp_range ( InputIterator first, InputIterator last, OutputIterator out,
0138     typename std::iterator_traits<InputIterator>::value_type const & lo, 
0139     typename std::iterator_traits<InputIterator>::value_type const & hi, Pred p )
0140   {
0141   // this could also be written with bind and std::transform
0142     while ( first != last )
0143         *out++ = boost::algorithm::clamp ( *first++, lo, hi, p );
0144     return out;
0145   } 
0146 
0147 /// \fn clamp_range ( const Range &r, OutputIterator out, 
0148 ///       typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type const & lo,
0149 ///       typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type const & hi,
0150 ///       Pred p )
0151 /// \return clamp the sequence of values [first, last) into [ lo, hi ]
0152 ///     using the comparison predicate p.
0153 /// 
0154 /// \param r     The range of values to be clamped
0155 /// \param out   An output iterator to write the clamped values into
0156 /// \param lo    The lower bound of the range to be clamped to
0157 /// \param hi    The upper bound of the range to be clamped to
0158 /// \param p     A predicate to use to compare the values.
0159 ///                 p ( a, b ) returns a boolean.
0160 //
0161 //  Disable this template if the first two parameters are the same type;
0162 //  In that case, the user will get the two iterator version.
0163   template<typename Range, typename OutputIterator, typename Pred> 
0164   BOOST_CXX14_CONSTEXPR typename boost::disable_if_c<boost::is_same<Range, OutputIterator>::value, OutputIterator>::type
0165   clamp_range ( const Range &r, OutputIterator out,
0166     typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type const & lo, 
0167     typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type const & hi,
0168     Pred p )
0169   {
0170     return boost::algorithm::clamp_range ( boost::begin ( r ), boost::end ( r ), out, lo, hi, p );
0171   } 
0172 
0173 
0174 }}
0175 
0176 #endif // BOOST_ALGORITHM_CLAMP_HPP