forked from boostorg/algorithm
minmax_macro v0.1
[SVN r3105]
This commit is contained in:
176
include/boost/algorithm/detail/minmax_macro_comeau.hpp
Executable file
176
include/boost/algorithm/detail/minmax_macro_comeau.hpp
Executable file
@ -0,0 +1,176 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// 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
|
167
include/boost/algorithm/detail/minmax_macro_msvc.hpp
Executable file
167
include/boost/algorithm/detail/minmax_macro_msvc.hpp
Executable file
@ -0,0 +1,167 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// 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
|
164
include/boost/algorithm/minmax_macro.hpp
Executable file
164
include/boost/algorithm/minmax_macro.hpp
Executable file
@ -0,0 +1,164 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// 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/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
|
Reference in New Issue
Block a user