forked from boostorg/algorithm
Documentation updates and new Doxyfile; new unit test and minor fix;
moved minmax_macro; new example. [SVN r52655]
This commit is contained in:
18
all/test/Jamfile.v2
Normal file
18
all/test/Jamfile.v2
Normal file
@ -0,0 +1,18 @@
|
||||
# Boost.All Library test Jamfile
|
||||
#
|
||||
# Copyright (C) 2009 Jesse Williamson
|
||||
#
|
||||
# Use, modification, and distribution is subject to the Boost Software
|
||||
# License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
#
|
||||
|
||||
import testing ;
|
||||
|
||||
{
|
||||
test-suite algorithm/all:
|
||||
: [ run all_test.cpp
|
||||
: : : : all ]
|
||||
;
|
||||
}
|
||||
|
46
all/test/all_test.cpp
Normal file
46
all/test/all_test.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
// (C) Copyright Jesse Williamson 2009
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/algorithm/all.hpp>
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
|
||||
#include <utility>
|
||||
#include <iostream>
|
||||
#include <functional>
|
||||
|
||||
// This prettyprinter is useful when debugging:
|
||||
template <class T>
|
||||
void show(std::vector<T>& v)
|
||||
{
|
||||
for(typename std::vector<T>::const_iterator i = v.begin(); i != v.end(); ++i)
|
||||
std::cout << *i << '\n';
|
||||
|
||||
std::cout << "----------" << std::endl;
|
||||
}
|
||||
|
||||
namespace ba = boost::algorithm;
|
||||
|
||||
void test_none()
|
||||
{
|
||||
// Note: The literal values here are tested against directly, careful if you change them:
|
||||
int some_numbers[] = { 1, 5, 0, 18, 1 };
|
||||
std::vector<int> vi(some_numbers, some_numbers + 5);
|
||||
|
||||
int some_letters[] = { 'a', 'q', 'n', 'y', 'n' };
|
||||
std::vector<char> vc(some_letters, some_letters + 5);
|
||||
|
||||
BOOST_CHECK_EQUAL(true, ba::none(vi, 100));
|
||||
BOOST_CHECK_EQUAL(false, ba::none(vi, 1));
|
||||
|
||||
BOOST_CHECK_EQUAL(true, ba::none(vc, 'z'));
|
||||
BOOST_CHECK_EQUAL(false, ba::none(vc, 'a'));
|
||||
}
|
||||
|
||||
int test_main( int , char* [] )
|
||||
{
|
||||
test_none();
|
||||
return 0;
|
||||
}
|
1417
doc/Doxyfile
Normal file
1417
doc/Doxyfile
Normal file
File diff suppressed because it is too large
Load Diff
7
example/Makefile
Normal file
7
example/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
|
||||
BOOST_ALGORITHM_INC=-I../../../ -I../../../boost/
|
||||
|
||||
CXX=c++
|
||||
|
||||
all:
|
||||
$(CXX) -Wall -o example_1 example_1.cpp $(BOOST_ALGORITHM_INC)
|
49
example/example_1.cpp
Normal file
49
example/example_1.cpp
Normal file
@ -0,0 +1,49 @@
|
||||
// Boost.Algorithm example
|
||||
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/algorithm.hpp>
|
||||
|
||||
using namespace boost::algorithm;
|
||||
using namespace boost::algorithm::sequence;
|
||||
|
||||
// Pretty-printer:
|
||||
template <class T>
|
||||
void show(std::vector<T>& v);
|
||||
|
||||
// Toy function that ignores parameters:
|
||||
int one_hundred(int&) { return 100; }
|
||||
|
||||
int main()
|
||||
{
|
||||
int some_numbers[] = { 0, 1, 32, 18, 5 };
|
||||
std::vector<int> vi(some_numbers, some_numbers + 5);
|
||||
|
||||
show(vi);
|
||||
|
||||
// none(): See that the values are not all 100:
|
||||
std::cout << "Are none of the values equal to 100? "
|
||||
<< ( none(vi, 100) ? "yes" : "no" ) << '\n';
|
||||
|
||||
// apply(): Change all the values to 100:
|
||||
apply(vi, one_hundred);
|
||||
|
||||
show(vi);
|
||||
|
||||
// all(): See that all of the values are now 100:
|
||||
std:: cout << "Are any values equal to 100? " <<
|
||||
( all(vi, 100) ? "yes" : "no" ) << '\n';
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void show(std::vector<T>& v)
|
||||
{
|
||||
for(typename std::vector<T>::const_iterator i = v.begin(); i != v.end(); ++i)
|
||||
std::cout << *i << '\n';
|
||||
|
||||
std::cout << "----------" << std::endl;
|
||||
}
|
||||
|
||||
/// \file example_1.cpp
|
||||
/// \brief Some examples using the Boost::Algorithm library.
|
@ -16,13 +16,13 @@
|
||||
#include <boost/range.hpp> // For boost::begin and boost::end
|
||||
|
||||
/// \file all.hpp
|
||||
/// \brief Boost implementation of various STL-type logical algorithms
|
||||
/// \brief Test ranges against predicates.
|
||||
/// \author Marshall Clow
|
||||
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
/// \fn all ( I first, I last, V val )
|
||||
/// \fn all ( I first, I last, const V &val )
|
||||
/// \brief Returns true if all elements in [first, last) are equal to 'val'
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
@ -39,7 +39,7 @@ namespace boost { namespace algorithm {
|
||||
return true;
|
||||
}
|
||||
|
||||
/// \fn all ( Range range, V val )
|
||||
/// \fn all ( Range range, const V &val )
|
||||
/// \brief Returns true if all elements in the range are equal to 'val'
|
||||
///
|
||||
/// \param range The input range
|
||||
@ -81,7 +81,7 @@ template<typename I, typename Pred>
|
||||
return all_if ( boost::begin ( range ), boost::end ( range ), p );
|
||||
}
|
||||
|
||||
/// \fn none ( I first, I last, V val )
|
||||
/// \fn none ( I first, I last, const V &val )
|
||||
/// \brief Returns true if none of the elements in [first, last) are equal to 'val'
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
@ -93,12 +93,12 @@ template<typename I, typename Pred>
|
||||
{
|
||||
while (first != last) {
|
||||
if ( *first++ == val )
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// \fn none ( Range range, V val )
|
||||
/// \fn none ( Range range, const V &val )
|
||||
/// \brief Returns true if none of the elements in the range are equal to 'val'
|
||||
///
|
||||
/// \param range The input range
|
||||
@ -140,7 +140,7 @@ template<typename I, typename Pred>
|
||||
return none_if ( boost::begin ( range ), boost::end ( range ), p );
|
||||
}
|
||||
|
||||
/// \fn any ( I first, I last, V val )
|
||||
/// \fn any ( I first, I last, const V &val )
|
||||
/// \brief Returns true if any of the elements in [first, last) are equal to 'val'
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
@ -157,7 +157,7 @@ template<typename I, typename Pred>
|
||||
return false;
|
||||
}
|
||||
|
||||
/// \fn any ( Range range, V val )
|
||||
/// \fn any ( Range range, const V &val )
|
||||
/// \brief Returns true if any of the elements in the range are equal to 'val'
|
||||
///
|
||||
/// \param range The input range
|
||||
@ -198,7 +198,7 @@ template<typename I, typename Pred>
|
||||
return any_if ( boost::begin ( range ), boost::end ( range ), p );
|
||||
}
|
||||
|
||||
/// \fn exists_and_only ( I first, I last, V val )
|
||||
/// \fn exists_and_only ( I first, I last, const V &val )
|
||||
/// \brief Returns true if the value 'val' exists only once in [first, last).
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
@ -214,7 +214,7 @@ template<typename I, typename Pred>
|
||||
return true;
|
||||
}
|
||||
|
||||
/// \fn exists_and_only ( Range range, V val )
|
||||
/// \fn exists_and_only ( Range range, const V &val )
|
||||
/// \brief Returns true if the value 'val' exists only once in the range.
|
||||
///
|
||||
/// \param range The input range
|
||||
|
@ -11,7 +11,7 @@
|
||||
#define BOOST_ALGORITHM_APPLY_HPP
|
||||
|
||||
/// \file apply.hpp
|
||||
/// \brief Boost implementation of sequence-modifying algorithms.
|
||||
/// \brief Apply predicates to ranges.
|
||||
/// \author Jesse Williamson
|
||||
|
||||
#include <boost/range.hpp>
|
||||
@ -22,7 +22,7 @@ namespace boost { namespace algorithm { namespace sequence {
|
||||
/// \brief Applies m to all elements from (begin, end) for which c is true.
|
||||
///
|
||||
/// \param begin The start of the sequence to modify
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param end One past the end of the input sequence
|
||||
/// \param m Unary mutator function object
|
||||
/// \param c Unary condition function object
|
||||
/// \return The mutator function object
|
||||
@ -38,7 +38,7 @@ Mutator apply_if(ForwardIter begin, ForwardIter end, Mutator m, ConditionPredica
|
||||
return m;
|
||||
}
|
||||
|
||||
/// \fn apply_if (Range r, Mutator m, ConditionPredicate c)
|
||||
/// \fn apply_if (ForwardReadableRange& r, Mutator m, ConditionPredicate c)
|
||||
/// \brief Applies m to all elements in the range r for which c is true.
|
||||
///
|
||||
/// \param r The range to modify
|
||||
@ -56,7 +56,7 @@ Mutator apply_if(ForwardReadableRange& R, Mutator m, ConditionPredicate c)
|
||||
/// \brief Applies m to all elements from (begin, end).
|
||||
///
|
||||
/// \param begin The start of the sequence to modify
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param end One past the end of the input sequence
|
||||
/// \param m Unary mutator function object
|
||||
/// \return The mutator function object
|
||||
///
|
||||
@ -69,7 +69,7 @@ Mutator apply(ForwardIter begin, ForwardIter end, Mutator m)
|
||||
return m;
|
||||
}
|
||||
|
||||
/// \fn apply (ForwardReadableRange r, Mutator m)
|
||||
/// \fn apply (ForwardReadableRange& r, Mutator m)
|
||||
/// \brief Applies m to all elements in the range r
|
||||
///
|
||||
/// \param r The range to modify
|
||||
|
@ -18,8 +18,7 @@
|
||||
#include <iterator> // for std::iterator_traits<>
|
||||
|
||||
/// \file copy.hpp
|
||||
/// \brief Boost implementation of various STL-type copying algorithms
|
||||
/// that were left out of the standard.
|
||||
/// \brief STL-type copy()-type algorithms that were left out of the standard.
|
||||
/// \author Marshall Clow
|
||||
|
||||
namespace boost { namespace algorithm { namespace sequence {
|
||||
@ -141,7 +140,7 @@ template<typename I,typename O>
|
||||
/// \return The (modified) output iterator
|
||||
///
|
||||
template<typename Range, typename O, typename Pred>
|
||||
std::pair<I,O> copy_while ( Range range, O res, Pred p )
|
||||
std::pair<typename Range::type,O> copy_while ( Range range, O res, Pred p )
|
||||
{
|
||||
return copy_while ( boost::begin ( range ), boost::end ( range ), res, p );
|
||||
}
|
||||
@ -175,7 +174,7 @@ template<typename I,typename O>
|
||||
/// \return The (modified) output iterator
|
||||
///
|
||||
template<typename Range, typename O, typename Pred>
|
||||
std::pair<I,O> reverse_copy_while ( Range range, O res, Pred p )
|
||||
std::pair<typename Range::type,O> reverse_copy_while ( Range range, O res, Pred p )
|
||||
{
|
||||
return reverse_copy_while ( boost::begin ( range ), boost::end ( range ), res, p );
|
||||
}
|
||||
@ -190,9 +189,14 @@ template<typename I,typename O>
|
||||
//
|
||||
// Marshall sez: What's the advantage of templatizing on count, rather than using std::size_t?
|
||||
//
|
||||
// Jesse says: I've kept the signature that was uncommented to stop Doxygen from complaining. Here's
|
||||
// the signature that was being discussed:
|
||||
// template <typename I, typename O>
|
||||
// O copy_n ( I first, typename std::iterator_traits<I>::difference_type count, O res )
|
||||
//
|
||||
// No range-based version here
|
||||
|
||||
/// \fn copy_n ( I first, typename iterator_traits<I>::difference_type count, O res )
|
||||
/// \fn copy_n ( I first, Size count, O res )
|
||||
/// \brief Copies n elements starting at 'first' into 'res'.
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
@ -202,8 +206,6 @@ template<typename I,typename O>
|
||||
///
|
||||
template <typename I, typename Size, typename O>
|
||||
O copy_n ( I first, Size count, O res )
|
||||
// template <typename I, typename O>
|
||||
// O copy_n ( I first, typename std::iterator_traits<I>::difference_type count, O res )
|
||||
{
|
||||
for ( ; count > 0; ++res, ++first, --count )
|
||||
*res = *first;
|
||||
@ -269,7 +271,7 @@ template<typename I,typename O>
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param out_true An output iterator to copy into
|
||||
/// \param out_false An output iterator to copy into
|
||||
/// \param p A predicate to determine which output sequence to copy into.
|
||||
/// \param pred A predicate to determine which output sequence to copy into.
|
||||
///
|
||||
///
|
||||
template <typename I, typename O1, typename O2, typename Pred>
|
||||
@ -287,14 +289,16 @@ template<typename I,typename O>
|
||||
}
|
||||
|
||||
|
||||
/// \fn partition_copy ( I first, I last, O1 out_true, O2 out_false, Pred pred )
|
||||
/// \fn partition_copy ( Range range, O1 out_true, O2 out_false, Pred pred )
|
||||
/// \brief Copies each element from the range into one of the two output sequences,
|
||||
/// depending on the result of the predicate
|
||||
///
|
||||
/// \param range The input range
|
||||
/// \param out_true An output iterator to copy into
|
||||
/// \param out_false An output iterator to copy into
|
||||
/// \param p A predicate to determine which output sequence to copy into.
|
||||
/// \param pred A predicate to determine which output sequence to copy into.
|
||||
///
|
||||
/// \note A range-based version of partition_copy.
|
||||
///
|
||||
template <typename Range, typename O1, typename O2, typename Pred>
|
||||
std::pair <O1, O2> partition_copy ( Range range, O1 out_true, O2 out_false, Pred pred )
|
||||
|
@ -1,176 +0,0 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// minmax_macro_comeau.hpp header file
|
||||
//
|
||||
// Copyright 2006 Eric Niebler.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Credits:
|
||||
// Scott Meyers - for carefully detailing the shortcomings of
|
||||
// std::min and std::max in his article "Min, max and more"
|
||||
// Andrei Alexandrescu - for the suggestion that ?: operator couls be useful
|
||||
// in solving Scott's long-standing min/max challenge.
|
||||
|
||||
#ifndef BOOST_MIN
|
||||
|
||||
#include <boost/mpl/or.hpp>
|
||||
#include <boost/mpl/eval_if.hpp>
|
||||
#include <boost/type_traits/is_array.hpp>
|
||||
#include <boost/type_traits/is_abstract.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
|
||||
namespace boost { namespace minmax_macro_detail_
|
||||
{
|
||||
template<typename Type>
|
||||
Type *encode_type(Type &) { return 0; }
|
||||
|
||||
template<typename Type>
|
||||
Type const *encode_type(Type const &) { return 0; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// max_impl
|
||||
template<typename Ret, typename Left, typename Right>
|
||||
struct max_impl
|
||||
{
|
||||
max_impl(Left &left, Right &right)
|
||||
: left_(left)
|
||||
, right_(right)
|
||||
{}
|
||||
|
||||
struct private_type_ { typedef private_type_ type; };
|
||||
|
||||
// can't ever return an array or an abstract type by value
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::mpl::eval_if<
|
||||
boost::mpl::or_<boost::is_abstract<Ret>, boost::is_array<Ret> >
|
||||
, private_type_
|
||||
, boost::remove_const<Ret>
|
||||
>::type value_type;
|
||||
|
||||
operator value_type()
|
||||
{
|
||||
return this->left_ < this->right_ ? this->right_ : this->left_;
|
||||
}
|
||||
|
||||
operator Ret &() const
|
||||
{
|
||||
return this->left_ < this->right_ ? this->right_ : this->left_;
|
||||
}
|
||||
|
||||
private:
|
||||
Left &left_;
|
||||
Right &right_;
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// max_fun
|
||||
template<typename Left, typename Right, typename Ret>
|
||||
max_impl<Ret, Left, Right>
|
||||
max_fun(Left &left, Right &right, Ret *)
|
||||
{
|
||||
return max_impl<Ret, Left, Right>(left, right);
|
||||
}
|
||||
|
||||
template<typename Left, typename Right, typename Ret>
|
||||
max_impl<Ret, Left const, Right>
|
||||
max_fun(Left const &left, Right &right, Ret *)
|
||||
{
|
||||
return max_impl<Ret, Left const, Right>(left, right);
|
||||
}
|
||||
|
||||
template<typename Left, typename Right, typename Ret>
|
||||
max_impl<Ret, Left, Right const>
|
||||
max_fun(Left &left, Right const &right, Ret *)
|
||||
{
|
||||
return max_impl<Ret, Left, Right const>(left, right);
|
||||
}
|
||||
|
||||
template<typename Left, typename Right, typename Ret>
|
||||
max_impl<Ret, Left const, Right const>
|
||||
max_fun(Left const &left, Right const &right, Ret *)
|
||||
{
|
||||
return max_impl<Ret, Left const, Right const>(left, right);
|
||||
}
|
||||
|
||||
#define BOOST_MAX(a,b)\
|
||||
(true\
|
||||
? boost::minmax_macro_detail_::max_fun((a), (b), \
|
||||
(true? 0 : boost::minmax_macro_detail_::encode_type(true? (a) : (b))))\
|
||||
: (true? (a) : (b)))
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// min_impl
|
||||
template<typename Ret, typename Left, typename Right>
|
||||
struct min_impl
|
||||
{
|
||||
min_impl(Left &left, Right &right)
|
||||
: left_(left)
|
||||
, right_(right)
|
||||
{}
|
||||
|
||||
struct private_type_ { typedef private_type_ type; };
|
||||
|
||||
// can't ever return an array or an abstract type by value
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::mpl::eval_if<
|
||||
boost::mpl::or_<boost::is_abstract<Ret>, boost::is_array<Ret> >
|
||||
, private_type_
|
||||
, boost::remove_const<Ret>
|
||||
>::type value_type;
|
||||
|
||||
operator value_type()
|
||||
{
|
||||
return this->left_ < this->right_ ? this->left_ : this->right_;
|
||||
}
|
||||
|
||||
operator Ret &() const
|
||||
{
|
||||
return this->left_ < this->right_ ? this->left_ : this->right_;
|
||||
}
|
||||
|
||||
private:
|
||||
Left &left_;
|
||||
Right &right_;
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// min_fun
|
||||
template<typename Left, typename Right, typename Ret>
|
||||
min_impl<Ret, Left, Right>
|
||||
min_fun(Left &left, Right &right, Ret *)
|
||||
{
|
||||
return min_impl<Ret, Left, Right>(left, right);
|
||||
}
|
||||
|
||||
template<typename Left, typename Right, typename Ret>
|
||||
min_impl<Ret, Left const, Right>
|
||||
min_fun(Left const &left, Right &right, Ret *)
|
||||
{
|
||||
return min_impl<Ret, Left const, Right>(left, right);
|
||||
}
|
||||
|
||||
template<typename Left, typename Right, typename Ret>
|
||||
min_impl<Ret, Left, Right const>
|
||||
min_fun(Left &left, Right const &right, Ret *)
|
||||
{
|
||||
return min_impl<Ret, Left, Right const>(left, right);
|
||||
}
|
||||
|
||||
template<typename Left, typename Right, typename Ret>
|
||||
min_impl<Ret, Left const, Right const>
|
||||
min_fun(Left const &left, Right const &right, Ret *)
|
||||
{
|
||||
return min_impl<Ret, Left const, Right const>(left, right);
|
||||
}
|
||||
|
||||
#define BOOST_MIN(a,b)\
|
||||
(true\
|
||||
? boost::minmax_macro_detail_::min_fun((a), (b), \
|
||||
(true? 0 : boost::minmax_macro_detail_::encode_type(true? (a) : (b))))\
|
||||
: (true? (a) : (b)))
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
@ -1,167 +0,0 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// minmax_macro_msvc.hpp header file
|
||||
//
|
||||
// Copyright 2006 Eric Niebler.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Credits:
|
||||
// Scott Meyers - for carefully detailing the shortcomings of
|
||||
// std::min and std::max in his article "Min, max and more"
|
||||
// Andrei Alexandrescu - for the suggestion that ?: operator couls be useful
|
||||
// in solving Scott's long-standing min/max challenge.
|
||||
|
||||
#ifndef BOOST_MIN
|
||||
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/logical.hpp>
|
||||
#include <boost/type_traits/is_array.hpp>
|
||||
#include <boost/type_traits/is_abstract.hpp>
|
||||
|
||||
namespace boost { namespace minmax_macro_detail_
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Define some utilities for assessing the properties of expressions
|
||||
//
|
||||
typedef char yes_type;
|
||||
typedef char (&no_type)[2];
|
||||
yes_type is_true(boost::mpl::true_ *);
|
||||
no_type is_true(boost::mpl::false_ *);
|
||||
|
||||
// Extracts the desired property from the expression without evaluating it
|
||||
#define BOOST_MINMAX_PROTECT(expr) \
|
||||
(static_cast<boost::mpl::bool_<1 == sizeof(boost::minmax_macro_detail_::is_true(expr))> *>(0))
|
||||
|
||||
template<typename Bool1, typename Bool2>
|
||||
inline boost::mpl::and_<Bool1, Bool2> *and_(Bool1 *, Bool2 *) { return 0; }
|
||||
|
||||
template<typename Bool>
|
||||
inline boost::mpl::not_<Bool> *not_(Bool *) { return 0; }
|
||||
|
||||
template<typename T>
|
||||
inline boost::mpl::false_ *is_rvalue_(T &, int) { return 0; }
|
||||
|
||||
template<typename T>
|
||||
inline boost::mpl::true_ *is_rvalue_(T const &, ...) { return 0; }
|
||||
|
||||
template<typename T>
|
||||
inline boost::is_array<T> *is_array_(T const &) { return 0; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Detect at compile-time whether an expression yields an rvalue or
|
||||
// an lvalue. This is rather non-standard, but MSVC seems to like it.
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// rvalue_probe
|
||||
//
|
||||
template<typename T>
|
||||
struct rvalue_probe
|
||||
{
|
||||
struct private_type_ {};
|
||||
// can't ever return an array by value
|
||||
typedef typename boost::mpl::if_<
|
||||
boost::mpl::or_<boost::is_abstract<T>, boost::is_array<T> >, private_type_, T
|
||||
>::type value_type;
|
||||
operator value_type();
|
||||
operator T &() const;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
rvalue_probe<T> const make_probe(T const &t);
|
||||
|
||||
# define BOOST_MINMAX_IS_RVALUE(T) \
|
||||
BOOST_MINMAX_PROTECT( \
|
||||
boost::minmax_macro_detail_::and_( \
|
||||
boost::minmax_macro_detail_::not_(boost::minmax_macro_detail_::is_array_(T)) \
|
||||
, boost::minmax_macro_detail_::is_rvalue_( \
|
||||
(true ? boost::minmax_macro_detail_::make_probe(T) : (T)), 0)))
|
||||
|
||||
template<typename Type>
|
||||
Type *encode_type(Type &) { return 0; }
|
||||
|
||||
template<typename Type>
|
||||
Type const *encode_type(Type const &) { return 0; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// max_fun
|
||||
template<typename Left, typename Right, typename Ret, typename IsRvalue>
|
||||
typename mpl::if_<IsRvalue, Ret, Ret &>::type
|
||||
max_fun(Left &left, Right &right, Ret *, IsRvalue *)
|
||||
{
|
||||
return left < right ? right : left;
|
||||
}
|
||||
|
||||
template<typename Left, typename Right, typename Ret, typename IsRvalue>
|
||||
typename mpl::if_<IsRvalue, Ret, Ret &>::type
|
||||
max_fun(Left const &left, Right &right, Ret *, IsRvalue *)
|
||||
{
|
||||
return left < right ? right : left;
|
||||
}
|
||||
|
||||
template<typename Left, typename Right, typename Ret, typename IsRvalue>
|
||||
typename mpl::if_<IsRvalue, Ret, Ret &>::type
|
||||
max_fun(Left &left, Right const &right, Ret *, IsRvalue *)
|
||||
{
|
||||
return left < right ? right : left;
|
||||
}
|
||||
|
||||
template<typename Left, typename Right, typename Ret, typename IsRvalue>
|
||||
typename mpl::if_<IsRvalue, Ret, Ret &>::type
|
||||
max_fun(Left const &left, Right const &right, Ret *, IsRvalue *)
|
||||
{
|
||||
return left < right ? right : left;
|
||||
}
|
||||
|
||||
#define BOOST_MAX(a,b)\
|
||||
boost::minmax_macro_detail_::max_fun(\
|
||||
(a) \
|
||||
, (b) \
|
||||
, (true? 0 : boost::minmax_macro_detail_::encode_type(true? (a) : (b))) \
|
||||
, BOOST_MINMAX_IS_RVALUE(true? (a) : (b)))
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// min_fun
|
||||
template<typename Left, typename Right, typename Ret, typename IsRvalue>
|
||||
typename mpl::if_<IsRvalue, Ret, Ret &>::type
|
||||
min_fun(Left &left, Right &right, Ret *, IsRvalue *)
|
||||
{
|
||||
return left < right ? left : right;
|
||||
}
|
||||
|
||||
template<typename Left, typename Right, typename Ret, typename IsRvalue>
|
||||
typename mpl::if_<IsRvalue, Ret, Ret &>::type
|
||||
min_fun(Left const &left, Right &right, Ret *, IsRvalue *)
|
||||
{
|
||||
return left < right ? left : right;
|
||||
}
|
||||
|
||||
template<typename Left, typename Right, typename Ret, typename IsRvalue>
|
||||
typename mpl::if_<IsRvalue, Ret, Ret &>::type
|
||||
min_fun(Left &left, Right const &right, Ret *, IsRvalue *)
|
||||
{
|
||||
return left < right ? left : right;
|
||||
}
|
||||
|
||||
template<typename Left, typename Right, typename Ret, typename IsRvalue>
|
||||
typename mpl::if_<IsRvalue, Ret, Ret &>::type
|
||||
min_fun(Left const &left, Right const &right, Ret *, IsRvalue *)
|
||||
{
|
||||
return left < right ? left : right;
|
||||
}
|
||||
|
||||
|
||||
#define BOOST_MIN(a,b)\
|
||||
boost::minmax_macro_detail_::min_fun(\
|
||||
(a) \
|
||||
, (b) \
|
||||
, (true? 0 : boost::minmax_macro_detail_::encode_type(true? (a) : (b))) \
|
||||
, BOOST_MINMAX_IS_RVALUE(true? (a) : (b)))
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
@ -13,7 +13,7 @@
|
||||
#include <boost/range.hpp>
|
||||
|
||||
/// \file find_if_not.hpp
|
||||
/// \brief Boost implementation of find_if_not() algorithm.
|
||||
/// \brief Return the first iterator in a range for which a predicate is false.
|
||||
/// \author Jesse Williamson
|
||||
|
||||
namespace boost { namespace algorithm { namespace sequence {
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include <boost/range.hpp> // For boost::begin and boost::end
|
||||
|
||||
/// \file for_each_if.hpp
|
||||
/// \brief Boost implementation for_each_if, which was left out of the standard.
|
||||
/// \brief Apply a functor to a range when a predicate is satisfied.
|
||||
/// \author Marshall Clow
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
@ -31,7 +31,7 @@ namespace boost { namespace algorithm {
|
||||
///
|
||||
///
|
||||
template<typename InputIterator, typename Pred, typename Func>
|
||||
UnaryFunction for_each_if ( InputIterator first, InputIterator last, Pred p, Func f )
|
||||
Func for_each_if ( InputIterator first, InputIterator last, Pred p, Func f )
|
||||
{
|
||||
while ( first != last )
|
||||
{
|
||||
|
@ -14,6 +14,7 @@
|
||||
// #include <boost/range.hpp> // For boost::begin and boost::end
|
||||
|
||||
/// \file iota.hpp
|
||||
/// \brief Generate and write sequences.
|
||||
/// \brief Boost implementation of iota, a proposed algorithm for TR2
|
||||
/// \author Marshall Clow
|
||||
|
||||
|
@ -1,165 +0,0 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// minmax_macro.hpp header file
|
||||
//
|
||||
// Copyright 2006 Eric Niebler.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Credits:
|
||||
// Scott Meyers - for carefully detailing the shortcomings of
|
||||
// std::min and std::max in his article "Min, max and more"
|
||||
// Andrei Alexandrescu - for the suggestion that ?: operator couls be useful
|
||||
// in solving Scott's long-standing min/max challenge.
|
||||
|
||||
#ifndef BOOST_MIN
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#if BOOST_WORKAROUND(__COMO_VERSION__, BOOST_TESTED_AT(4245))
|
||||
|
||||
# include <boost/algorithm/detail/minmax_macro_comeau.hpp>
|
||||
|
||||
#elif BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1400))
|
||||
|
||||
# include <boost/algorithm/detail/minmax_macro_msvc.hpp>
|
||||
|
||||
#else
|
||||
|
||||
namespace boost { namespace minmax_macro_detail_
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// max_impl
|
||||
template<typename Left, typename Right>
|
||||
struct max_impl
|
||||
{
|
||||
max_impl(Left &left, Right &right)
|
||||
: left_(left)
|
||||
, right_(right)
|
||||
{}
|
||||
|
||||
template<typename Rvalue>
|
||||
operator Rvalue ()
|
||||
{
|
||||
return this->left_ < this->right_ ? this->right_ : this->left_;
|
||||
}
|
||||
|
||||
template<typename Lvalue>
|
||||
operator Lvalue &() const
|
||||
{
|
||||
return this->left_ < this->right_ ? this->right_ : this->left_;
|
||||
}
|
||||
|
||||
#if BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(3))
|
||||
operator max_impl & () { return *this; }
|
||||
#endif
|
||||
|
||||
private:
|
||||
Left &left_;
|
||||
Right &right_;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// max_fun
|
||||
template<typename Left, typename Right>
|
||||
max_impl<Left, Right>
|
||||
max_fun(Left &left, Right &right)
|
||||
{
|
||||
return max_impl<Left, Right>(left, right);
|
||||
}
|
||||
|
||||
template<typename Left, typename Right>
|
||||
max_impl<Left const, Right>
|
||||
max_fun(Left const &left, Right &right)
|
||||
{
|
||||
return max_impl<Left const, Right>(left, right);
|
||||
}
|
||||
|
||||
template<typename Left, typename Right>
|
||||
max_impl<Left, Right const>
|
||||
max_fun(Left &left, Right const &right)
|
||||
{
|
||||
return max_impl<Left, Right const>(left, right);
|
||||
}
|
||||
|
||||
template<typename Left, typename Right>
|
||||
max_impl<Left const, Right const>
|
||||
max_fun(Left const &left, Right const &right)
|
||||
{
|
||||
return max_impl<Left const, Right const>(left, right);
|
||||
}
|
||||
|
||||
#define BOOST_MAX(a,b)\
|
||||
(true? boost::minmax_macro_detail_::max_fun((a), (b)) : (true? (a) : (b)))
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// min_impl
|
||||
template<typename Left, typename Right>
|
||||
struct min_impl
|
||||
{
|
||||
min_impl(Left &left, Right &right)
|
||||
: left_(left)
|
||||
, right_(right)
|
||||
{}
|
||||
|
||||
template<typename Rvalue>
|
||||
operator Rvalue ()
|
||||
{
|
||||
return this->left_ < this->right_ ? this->left_ : this->right_;
|
||||
}
|
||||
|
||||
template<typename Lvalue>
|
||||
operator Lvalue &() const
|
||||
{
|
||||
return this->left_ < this->right_ ? this->left_ : this->right_;
|
||||
}
|
||||
|
||||
#if BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(3))
|
||||
operator min_impl & () { return *this; }
|
||||
#endif
|
||||
|
||||
private:
|
||||
Left &left_;
|
||||
Right &right_;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// min_fun
|
||||
template<typename Left, typename Right>
|
||||
min_impl<Left, Right>
|
||||
min_fun(Left &left, Right &right)
|
||||
{
|
||||
return min_impl<Left, Right>(left, right);
|
||||
}
|
||||
|
||||
template<typename Left, typename Right>
|
||||
min_impl<Left const, Right>
|
||||
min_fun(Left const &left, Right &right)
|
||||
{
|
||||
return min_impl<Left const, Right>(left, right);
|
||||
}
|
||||
|
||||
template<typename Left, typename Right>
|
||||
min_impl<Left, Right const>
|
||||
min_fun(Left &left, Right const &right)
|
||||
{
|
||||
return min_impl<Left, Right const>(left, right);
|
||||
}
|
||||
|
||||
template<typename Left, typename Right>
|
||||
min_impl<Left const, Right const>
|
||||
min_fun(Left const &left, Right const &right)
|
||||
{
|
||||
return min_impl<Left const, Right const>(left, right);
|
||||
}
|
||||
|
||||
#define BOOST_MIN(a,b)\
|
||||
(true? boost::minmax_macro_detail_::min_fun((a), (b)) : (true? (a) : (b)))
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
@ -16,12 +16,12 @@
|
||||
|
||||
|
||||
/// \file select.hpp
|
||||
/// \brief Boost implementation select1st and select2nd.
|
||||
/// \brief Choose the first or second element of a Pair.
|
||||
/// \author Marshall Clow
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
/// \fn select1st
|
||||
/// \struct select1st
|
||||
/// \brief Unary function that returns the first element of a std::pair
|
||||
///
|
||||
/// \param p The pair.
|
||||
@ -35,7 +35,7 @@ namespace boost { namespace algorithm {
|
||||
typename Pair::first_type& operator()( Pair& p) const { return p.first; }
|
||||
};
|
||||
|
||||
/// \fn select2nd
|
||||
/// \struct select2nd
|
||||
/// \brief Unary function that returns the first element of a std::pair
|
||||
///
|
||||
/// \param p The pair.
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include <boost/range.hpp>
|
||||
|
||||
/// \file transform_if.hpp
|
||||
/// \brief Boost implementation of transform_if() algorithm.
|
||||
/// \brief Apply operations across ranges when a predicate is true, storing returned values.
|
||||
/// \author Jesse Williamson
|
||||
|
||||
namespace boost { namespace algorithm { namespace sequence {
|
||||
|
@ -1,21 +0,0 @@
|
||||
# (C) Copyright 2004: Eric Niebler
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
# bring in rules for testing
|
||||
import testing ;
|
||||
|
||||
project
|
||||
: requirements
|
||||
<library>/boost/test//boost_unit_test_framework
|
||||
<link>static
|
||||
<include>../../../..
|
||||
;
|
||||
|
||||
test-suite "minmax_macro"
|
||||
: [ run basic.cpp ]
|
||||
[ run promotions.cpp ]
|
||||
[ run rvalue_lvalue.cpp ]
|
||||
[ run tricky.cpp ]
|
||||
[ run eval_once.cpp ]
|
||||
;
|
@ -1,44 +0,0 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// basic.hpp test file
|
||||
//
|
||||
// Copyright 2006 Eric Niebler.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/algorithm/minmax_macro.hpp>
|
||||
|
||||
void basic_min_test()
|
||||
{
|
||||
BOOST_CHECK_EQUAL(1, BOOST_MIN(1,2));
|
||||
BOOST_CHECK_EQUAL(1, BOOST_MIN(2,1));
|
||||
|
||||
int one=1, two=2;
|
||||
BOOST_CHECK_EQUAL(one, BOOST_MIN(one,two));
|
||||
BOOST_CHECK_EQUAL(one, BOOST_MIN(two,one));
|
||||
}
|
||||
|
||||
void basic_max_test()
|
||||
{
|
||||
BOOST_CHECK_EQUAL(2, BOOST_MAX(1,2));
|
||||
BOOST_CHECK_EQUAL(2, BOOST_MAX(2,1));
|
||||
|
||||
int one=1, two=2;
|
||||
BOOST_CHECK_EQUAL(two, BOOST_MAX(one,two));
|
||||
BOOST_CHECK_EQUAL(two, BOOST_MAX(two,one));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// init_unit_test_suite
|
||||
//
|
||||
boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] )
|
||||
{
|
||||
boost::unit_test::test_suite *test = BOOST_TEST_SUITE("basic min/max test");
|
||||
|
||||
test->add(BOOST_TEST_CASE(&basic_min_test));
|
||||
test->add(BOOST_TEST_CASE(&basic_max_test));
|
||||
|
||||
return test;
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// eval_once.hpp test file
|
||||
//
|
||||
// Copyright 2006 Eric Niebler.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/algorithm/minmax_macro.hpp>
|
||||
|
||||
void test_eval_once()
|
||||
{
|
||||
int i = 0;
|
||||
int j = 1;
|
||||
|
||||
int k = BOOST_MIN(i++,j);
|
||||
BOOST_CHECK_EQUAL(1, i);
|
||||
BOOST_CHECK_EQUAL(0, k);
|
||||
|
||||
k = BOOST_MAX(i,++j);
|
||||
BOOST_CHECK_EQUAL(2, j);
|
||||
BOOST_CHECK_EQUAL(2, k);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// init_unit_test_suite
|
||||
//
|
||||
boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] )
|
||||
{
|
||||
boost::unit_test::test_suite *test = BOOST_TEST_SUITE("eval_once min/max test");
|
||||
|
||||
test->add(BOOST_TEST_CASE(&test_eval_once));
|
||||
|
||||
return test;
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// promotions.hpp test file
|
||||
//
|
||||
// Copyright 2006 Eric Niebler.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/algorithm/minmax_macro.hpp>
|
||||
|
||||
template<typename Result, typename T> void check_is_same(T)
|
||||
{
|
||||
BOOST_MPL_ASSERT((boost::is_same<T,Result>));
|
||||
}
|
||||
|
||||
void test_promotions()
|
||||
{
|
||||
char ch = 0;
|
||||
short sh = 0;
|
||||
int in = 0;
|
||||
unsigned un = 0;
|
||||
float fl = 0;
|
||||
double db = 0;
|
||||
|
||||
check_is_same<int>(BOOST_MIN(ch,sh));
|
||||
check_is_same<int>(BOOST_MAX(ch,sh));
|
||||
check_is_same<int>(BOOST_MIN(ch,in));
|
||||
check_is_same<int>(BOOST_MAX(ch,in));
|
||||
|
||||
check_is_same<unsigned>(BOOST_MIN(un,in));
|
||||
check_is_same<unsigned>(BOOST_MAX(un,in));
|
||||
|
||||
check_is_same<float>(BOOST_MIN(in,fl));
|
||||
check_is_same<float>(BOOST_MAX(in,fl));
|
||||
|
||||
check_is_same<double>(BOOST_MIN(db,fl));
|
||||
check_is_same<double>(BOOST_MAX(db,fl));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// init_unit_test_suite
|
||||
//
|
||||
boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] )
|
||||
{
|
||||
boost::unit_test::test_suite *test = BOOST_TEST_SUITE("promotions min/max test");
|
||||
|
||||
test->add(BOOST_TEST_CASE(&test_promotions));
|
||||
|
||||
return test;
|
||||
}
|
@ -1,94 +0,0 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// rvalue_lvalue.hpp test file
|
||||
//
|
||||
// Copyright 2006 Eric Niebler.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Test code from Howard Hinnant (TODO: get permission!)
|
||||
|
||||
#include <boost/test/included/unit_test.hpp>
|
||||
#include <boost/algorithm/minmax_macro.hpp>
|
||||
|
||||
class A
|
||||
{
|
||||
private:
|
||||
int i_;
|
||||
public:
|
||||
A(int i) : i_(i) {}
|
||||
~A() {i_ = 0;}
|
||||
|
||||
A(const A& a) : i_(a.i_) {}
|
||||
|
||||
operator int() const {return i_;}
|
||||
|
||||
friend bool operator<(const A& x, const A& y)
|
||||
{return x.i_ < y.i_;}
|
||||
|
||||
friend bool operator==(const A& x, const A& y)
|
||||
{return x.i_ == y.i_;}
|
||||
};
|
||||
|
||||
void test_rvalue_lvalue()
|
||||
{
|
||||
// lvalues of the same type:
|
||||
{
|
||||
A a3(3);
|
||||
A a2(2);
|
||||
BOOST_MIN(a2, a3) = A(1); // a2 == 1, no copy, no move
|
||||
BOOST_CHECK_EQUAL(a2, A(1));
|
||||
BOOST_CHECK_EQUAL(a3, A(3));
|
||||
}
|
||||
|
||||
//{
|
||||
// // lvalues of the same type with different cv
|
||||
// const A a3(3);
|
||||
// A a2(2);
|
||||
// BOOST_MIN(a2, a3) = A(1); // illegal operands 'const A' = 'A'
|
||||
//}
|
||||
|
||||
{
|
||||
const A a3(3);
|
||||
A a2(2);
|
||||
const A& a_ref = BOOST_MIN(a2, a3);
|
||||
a2 = A(1); // a_ref == 1, a_ref refers to a2, no copy, no move
|
||||
BOOST_CHECK_EQUAL(a_ref, A(1));
|
||||
}
|
||||
|
||||
{
|
||||
// lvalue / rvalue mix of the same type
|
||||
A a3(3);
|
||||
const A& a_ref = BOOST_MIN(A(2), a3);
|
||||
BOOST_CHECK_EQUAL(a_ref, A(2));
|
||||
// a_ref refers to temporary returned (by value) from BOOST_MIN, a_ref == 2, A(A&&) executed to move from A(2)
|
||||
// A(const A&) - or some copy constructor - required to be accessible
|
||||
}
|
||||
|
||||
{
|
||||
A a1(1);
|
||||
const A& a_ref = BOOST_MIN(A(2), a1);
|
||||
BOOST_CHECK_EQUAL(a_ref, A(1));
|
||||
// a_ref refers to temporary returned (by value) from BOOST_MIN, a_ref == 1, A(const A&) executed to copy from a1
|
||||
}
|
||||
|
||||
{
|
||||
// rvalue / rvalue
|
||||
const A& a_ref = BOOST_MIN(A(2), A(3));
|
||||
BOOST_CHECK_EQUAL(a_ref, A(2));
|
||||
// a_ref refers to temporary returned (by value) from BOOST_MIN, a_ref == 2, A(A&&) executed to move from A(2)
|
||||
// accessible copy constructor not required
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// init_unit_test_suite
|
||||
//
|
||||
boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] )
|
||||
{
|
||||
boost::unit_test::test_suite *test = BOOST_TEST_SUITE("rvalue/lvalue min/max test");
|
||||
|
||||
test->add(BOOST_TEST_CASE(&test_rvalue_lvalue));
|
||||
|
||||
return test;
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// tricky.hpp test file
|
||||
//
|
||||
// Copyright 2006 Eric Niebler.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/algorithm/minmax_macro.hpp>
|
||||
|
||||
struct Base
|
||||
{
|
||||
virtual bool operator <(Base const &) const = 0;
|
||||
};
|
||||
|
||||
struct Derived : Base
|
||||
{
|
||||
virtual bool operator <(Base const &that) const
|
||||
{
|
||||
return dynamic_cast<void const*>(this) < dynamic_cast<void const*>(&that);
|
||||
}
|
||||
};
|
||||
|
||||
void test_tricky()
|
||||
{
|
||||
Derived d;
|
||||
Base &b = d;
|
||||
|
||||
Base &lvalue = BOOST_MIN(d,b);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// init_unit_test_suite
|
||||
//
|
||||
boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] )
|
||||
{
|
||||
boost::unit_test::test_suite *test = BOOST_TEST_SUITE("tricky min/max test");
|
||||
|
||||
test->add(BOOST_TEST_CASE(&test_tricky));
|
||||
|
||||
return test;
|
||||
}
|
Reference in New Issue
Block a user