forked from boostorg/iterator
Many changes from Oxford
[SVN r1137]
This commit is contained in:
@@ -13,42 +13,98 @@
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/apply_if.hpp>
|
||||
#include <boost/mpl/identity.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/or.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <iterator>
|
||||
|
||||
#if BOOST_WORKAROUND(__MWERKS__, <=0x2407)
|
||||
# define BOOST_NO_IS_CONVERTIBLE // "Convertible does not provide enough/is not working"
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace boost
|
||||
{
|
||||
|
||||
// faked new old-style categories needed to make new->old mapping
|
||||
// work
|
||||
namespace detail
|
||||
{
|
||||
struct null_category_tag {};
|
||||
struct input_output_iterator_tag : std::input_iterator_tag, std::output_iterator_tag {};
|
||||
}
|
||||
|
||||
//
|
||||
// Access Categories
|
||||
//
|
||||
struct readable_iterator_tag
|
||||
{
|
||||
typedef std::input_iterator_tag max_category;
|
||||
};
|
||||
|
||||
struct writable_iterator_tag
|
||||
{
|
||||
typedef std::output_iterator_tag max_category;
|
||||
};
|
||||
|
||||
struct swappable_iterator_tag
|
||||
{
|
||||
typedef detail::null_category_tag max_category;
|
||||
};
|
||||
|
||||
struct readable_writable_iterator_tag
|
||||
: virtual readable_iterator_tag
|
||||
, virtual writable_iterator_tag
|
||||
, virtual swappable_iterator_tag
|
||||
{
|
||||
typedef detail::input_output_iterator_tag max_category;
|
||||
};
|
||||
|
||||
struct readable_lvalue_iterator_tag
|
||||
: virtual readable_iterator_tag
|
||||
{
|
||||
typedef std::random_access_iterator_tag max_category;
|
||||
};
|
||||
|
||||
struct writable_lvalue_iterator_tag
|
||||
: virtual public readable_writable_iterator_tag
|
||||
, virtual public readable_lvalue_iterator_tag
|
||||
{
|
||||
typedef std::random_access_iterator_tag max_category;
|
||||
};
|
||||
|
||||
//
|
||||
// Categories
|
||||
//
|
||||
// !! Fix detection functions if categories
|
||||
// are changed.
|
||||
//
|
||||
|
||||
// Return Type Categories
|
||||
struct readable_iterator_tag { };
|
||||
struct writable_iterator_tag { };
|
||||
struct swappable_iterator_tag :
|
||||
virtual public readable_iterator_tag, // Not sure about this change -JGS
|
||||
virtual public writable_iterator_tag { };
|
||||
struct constant_lvalue_iterator_tag :
|
||||
virtual public readable_iterator_tag { };
|
||||
struct mutable_lvalue_iterator_tag :
|
||||
virtual public swappable_iterator_tag,
|
||||
virtual public constant_lvalue_iterator_tag { };
|
||||
|
||||
// Traversal Categories
|
||||
struct input_traversal_tag { };
|
||||
struct output_traversal_tag { };
|
||||
struct forward_traversal_tag : virtual public input_traversal_tag,
|
||||
virtual public output_traversal_tag { };
|
||||
struct bidirectional_traversal_tag : virtual public forward_traversal_tag { };
|
||||
struct random_access_traversal_tag : virtual public bidirectional_traversal_tag { };
|
||||
//
|
||||
struct incrementable_iterator_tag
|
||||
{
|
||||
typedef std::output_iterator_tag max_category;
|
||||
};
|
||||
|
||||
struct single_pass_iterator_tag
|
||||
: incrementable_iterator_tag
|
||||
{
|
||||
typedef detail::input_output_iterator_tag max_category;
|
||||
};
|
||||
|
||||
struct forward_traversal_tag
|
||||
: single_pass_iterator_tag
|
||||
{
|
||||
typedef std::forward_iterator_tag max_category;
|
||||
};
|
||||
|
||||
struct bidirectional_traversal_tag
|
||||
: forward_traversal_tag
|
||||
{
|
||||
typedef std::bidirectional_iterator_tag max_category;
|
||||
};
|
||||
|
||||
struct random_access_traversal_tag
|
||||
: bidirectional_traversal_tag
|
||||
{
|
||||
typedef std::random_access_iterator_tag max_category;
|
||||
};
|
||||
|
||||
struct error_iterator_tag { };
|
||||
|
||||
@@ -57,384 +113,162 @@ namespace boost {
|
||||
//
|
||||
// Tag detection meta functions
|
||||
//
|
||||
// Needed to work with compilers
|
||||
// without working is_convertible
|
||||
//
|
||||
|
||||
#ifndef BOOST_NO_IS_CONVERTIBLE
|
||||
template <class Category>
|
||||
struct is_input_iterator :
|
||||
is_convertible<Category*, std::input_iterator_tag*>
|
||||
{
|
||||
};
|
||||
|
||||
template <class Category>
|
||||
struct is_output_iterator :
|
||||
is_convertible<Category*, std::output_iterator_tag*>
|
||||
{
|
||||
};
|
||||
|
||||
template <class Category>
|
||||
struct is_forward_iterator :
|
||||
is_convertible<Category*, std::forward_iterator_tag*>
|
||||
{
|
||||
};
|
||||
|
||||
template <class Category>
|
||||
struct is_bidirectional_iterator :
|
||||
is_convertible<Category*, std::bidirectional_iterator_tag*>
|
||||
{
|
||||
};
|
||||
|
||||
template <class Category>
|
||||
struct is_random_access_iterator :
|
||||
is_convertible<Category*, std::random_access_iterator_tag*>
|
||||
{
|
||||
};
|
||||
|
||||
template <class Category>
|
||||
struct is_readable_iterator :
|
||||
is_convertible<Category*, readable_iterator_tag*>
|
||||
{ };
|
||||
|
||||
template <class Category>
|
||||
struct is_writable_iterator :
|
||||
is_convertible<Category*, writable_iterator_tag*>
|
||||
{ };
|
||||
|
||||
template <class Category>
|
||||
struct is_swappable_iterator :
|
||||
is_convertible<Category*, swappable_iterator_tag*>
|
||||
{ };
|
||||
|
||||
template <class Category>
|
||||
struct is_constant_lvalue_iterator :
|
||||
is_convertible<Category*, constant_lvalue_iterator_tag*>
|
||||
{ };
|
||||
|
||||
template <class Category>
|
||||
struct is_mutable_lvalue_iterator :
|
||||
is_convertible<Category*, mutable_lvalue_iterator_tag*>
|
||||
{ };
|
||||
|
||||
template <class Category>
|
||||
struct is_input_traversal_iterator :
|
||||
is_convertible<Category*, input_traversal_tag*>
|
||||
{ };
|
||||
|
||||
template <class Category>
|
||||
struct is_output_traversal_iterator :
|
||||
is_convertible<Category*, output_traversal_tag*>
|
||||
{ };
|
||||
|
||||
template <class Category>
|
||||
struct is_forward_traversal_iterator :
|
||||
is_convertible<Category*, forward_traversal_tag*>
|
||||
{ };
|
||||
|
||||
template <class Category>
|
||||
struct is_bidirectional_traversal_iterator :
|
||||
is_convertible<Category*, bidirectional_traversal_tag*>
|
||||
{ };
|
||||
|
||||
template <class Category>
|
||||
struct is_random_access_traversal_iterator :
|
||||
is_convertible<Category*, random_access_traversal_tag*>
|
||||
{ };
|
||||
|
||||
#else
|
||||
//
|
||||
// We cannot detect the iterator category for custom
|
||||
// tag types. For custom tag types false_ is returned
|
||||
//
|
||||
// As a result the std iterator category detection functions
|
||||
// can't detect the iterator category of the new iterator_tag template.
|
||||
//
|
||||
|
||||
//
|
||||
// std iterator categories
|
||||
//
|
||||
|
||||
template <class Category>
|
||||
struct is_random_access_iterator :
|
||||
mpl::false_
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct is_random_access_iterator<std::random_access_iterator_tag> :
|
||||
mpl::true_
|
||||
{};
|
||||
|
||||
template <class Category>
|
||||
struct is_bidirectional_iterator :
|
||||
is_random_access_iterator< Category >
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct is_bidirectional_iterator<std::bidirectional_iterator_tag> :
|
||||
mpl::true_
|
||||
{};
|
||||
|
||||
template <class Category>
|
||||
struct is_forward_iterator :
|
||||
is_bidirectional_iterator< Category >
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct is_forward_iterator<std::forward_iterator_tag> :
|
||||
mpl::true_
|
||||
{};
|
||||
|
||||
template <class Category>
|
||||
struct is_output_iterator :
|
||||
is_forward_iterator< Category >
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct is_output_iterator<std::output_iterator_tag> :
|
||||
mpl::true_
|
||||
{};
|
||||
|
||||
template <class Category>
|
||||
struct is_input_iterator :
|
||||
is_forward_iterator< Category >
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct is_input_iterator<std::input_iterator_tag> :
|
||||
mpl::true_
|
||||
{};
|
||||
|
||||
//
|
||||
// Return type
|
||||
//
|
||||
// The nested is_category template class are used for
|
||||
// minimum category detection in iterator_adaptors.
|
||||
// They are basically a poore mans is_derived replacement.
|
||||
//
|
||||
// A implementation may look like this
|
||||
//
|
||||
// template <class Cat1, class Cat2>
|
||||
// struct min_cat
|
||||
// : mpl::if_< is_return_category< Cat1 >::template is_category< Cat2 >,
|
||||
// Cat1,
|
||||
// mpl::if_< is_return_category<Cat2>::template is_category<Cat1>,
|
||||
// Cat2,
|
||||
// error_type
|
||||
// >
|
||||
// > {};
|
||||
|
||||
template <class Category>
|
||||
struct is_mutable_lvalue_iterator :
|
||||
mpl::false_
|
||||
{
|
||||
template <class T>
|
||||
struct is_category
|
||||
: boost::mpl::false_ {};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_mutable_lvalue_iterator<mutable_lvalue_iterator_tag> :
|
||||
mpl::true_
|
||||
{
|
||||
template <class Category>
|
||||
struct is_category
|
||||
: is_mutable_lvalue_iterator<Category> {};
|
||||
};
|
||||
|
||||
template <class Category>
|
||||
struct is_constant_lvalue_iterator :
|
||||
is_mutable_lvalue_iterator<Category>
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct is_constant_lvalue_iterator<constant_lvalue_iterator_tag> :
|
||||
mpl::true_
|
||||
{
|
||||
template <class Category>
|
||||
struct is_category
|
||||
: is_constant_lvalue_iterator<Category> {};
|
||||
};
|
||||
|
||||
template <class Category>
|
||||
struct is_swappable_iterator :
|
||||
is_constant_lvalue_iterator<Category>
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct is_swappable_iterator<swappable_iterator_tag> :
|
||||
mpl::true_
|
||||
{
|
||||
template <class Category>
|
||||
struct is_category
|
||||
: is_swappable_iterator<Category> {};
|
||||
};
|
||||
|
||||
template <class Category>
|
||||
struct is_readable_iterator :
|
||||
mpl::if_< is_swappable_iterator<Category>,
|
||||
is_swappable_iterator<Category>,
|
||||
is_constant_lvalue_iterator<Category> >::type
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct is_readable_iterator<readable_iterator_tag> :
|
||||
mpl::true_
|
||||
{
|
||||
template <class Category>
|
||||
struct is_category
|
||||
: is_readable_iterator<Category> {};
|
||||
};
|
||||
|
||||
template <class Category>
|
||||
struct is_writable_iterator :
|
||||
is_swappable_iterator<Category>
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct is_writable_iterator<writable_iterator_tag> :
|
||||
mpl::true_
|
||||
{
|
||||
template <class Category>
|
||||
struct is_category
|
||||
: is_writable_iterator<Category> {};
|
||||
};
|
||||
|
||||
template <class Category>
|
||||
struct is_return_category
|
||||
: mpl::if_< is_writable_iterator<Category>,
|
||||
is_writable_iterator<Category>,
|
||||
is_readable_iterator<Category> >::type
|
||||
{
|
||||
};
|
||||
|
||||
//
|
||||
// Traversal
|
||||
//
|
||||
|
||||
template <class Category>
|
||||
struct is_random_access_traversal_iterator :
|
||||
mpl::false_
|
||||
{
|
||||
template <class T>
|
||||
struct is_category
|
||||
: boost::mpl::false_ {};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_random_access_traversal_iterator<random_access_traversal_tag> :
|
||||
mpl::true_
|
||||
{
|
||||
template <class Category>
|
||||
struct is_category
|
||||
: is_random_access_traversal_iterator<Category> {};
|
||||
};
|
||||
|
||||
template <class Category>
|
||||
struct is_bidirectional_traversal_iterator :
|
||||
is_random_access_traversal_iterator< Category >
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct is_bidirectional_traversal_iterator<bidirectional_traversal_tag> :
|
||||
mpl::true_
|
||||
{
|
||||
template <class Category>
|
||||
struct is_category
|
||||
: is_bidirectional_traversal_iterator<Category> {};
|
||||
};
|
||||
|
||||
template <class Category>
|
||||
struct is_forward_traversal_iterator :
|
||||
is_bidirectional_traversal_iterator< Category >
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct is_forward_traversal_iterator<forward_traversal_tag> :
|
||||
mpl::true_
|
||||
{
|
||||
template <class Category>
|
||||
struct is_category
|
||||
: is_forward_traversal_iterator<Category> {};
|
||||
};
|
||||
|
||||
template <class Category>
|
||||
struct is_input_traversal_iterator :
|
||||
is_forward_traversal_iterator< Category >
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct is_input_traversal_iterator<input_traversal_tag> :
|
||||
mpl::true_
|
||||
{
|
||||
template <class Category>
|
||||
struct is_category
|
||||
: is_input_traversal_iterator<Category> {};
|
||||
};
|
||||
|
||||
template <class Category>
|
||||
struct is_output_traversal_iterator :
|
||||
is_forward_traversal_iterator< Category >
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct is_output_traversal_iterator<output_traversal_tag> :
|
||||
mpl::true_
|
||||
{
|
||||
template <class Category>
|
||||
struct is_category
|
||||
: is_output_traversal_iterator<Category> {};
|
||||
};
|
||||
|
||||
template <class Category>
|
||||
struct is_traversal_category
|
||||
: mpl::if_< is_input_traversal_iterator<Category>,
|
||||
is_input_traversal_iterator<Category>,
|
||||
is_output_traversal_iterator<Category> >::type
|
||||
{};
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
|
||||
// I bet this is defined somewhere else. Let's wait and see.
|
||||
//
|
||||
struct error_type;
|
||||
|
||||
#ifdef BOOST_NO_IS_CONVERTIBLE
|
||||
template <class Cat1, class Cat2>
|
||||
struct minimum_return_category
|
||||
: mpl::if_< is_return_category< Cat1 >::template is_category< Cat2 >,
|
||||
Cat1,
|
||||
mpl::if_< is_return_category<Cat2>::template is_category<Cat1>,
|
||||
Cat2,
|
||||
error_type
|
||||
>
|
||||
> {};
|
||||
|
||||
template <class Cat1, class Cat2>
|
||||
struct minimum_traversal_category
|
||||
: mpl::if_< is_traversal_category< Cat1 >::template is_category< Cat2 >,
|
||||
Cat1,
|
||||
mpl::if_< is_traversal_category<Cat2>::template is_category<Cat1>,
|
||||
Cat2,
|
||||
error_type
|
||||
>
|
||||
> {};
|
||||
|
||||
template <class T1, class T2>
|
||||
struct minimum_category_select
|
||||
: mpl::if_< is_same< typename T1::type, error_type >,
|
||||
T2,
|
||||
T1 >
|
||||
{};
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_NO_IS_CONVERTIBLE
|
||||
template <class Base, class Derived>
|
||||
struct is_base_or_same :
|
||||
mpl::or_< is_same< Base, Derived >,
|
||||
is_base_and_derived< Base, Derived > >
|
||||
struct is_same_or_derived
|
||||
# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
: mpl::or_<
|
||||
is_same<Base, Derived>
|
||||
, is_base_and_derived<Base, Derived>
|
||||
>
|
||||
{};
|
||||
# else
|
||||
: is_base_and_derived<Base, Derived>
|
||||
{};
|
||||
|
||||
template <class T> struct is_same_or_derived<T,T> : mpl::true_ {};
|
||||
# endif
|
||||
|
||||
template <class Tag, class T>
|
||||
struct is_tag
|
||||
: mpl::or_<
|
||||
# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
is_same_or_derived<Tag, T>
|
||||
# else
|
||||
is_base_and_derived<Tag, T>
|
||||
# endif
|
||||
|
||||
// Because we can't actually get forward_iterator_tag to
|
||||
// derive from input_output_iterator_tag, we need this
|
||||
// case.
|
||||
, mpl::and_<
|
||||
is_same_or_derived<Tag,detail::input_output_iterator_tag>
|
||||
, is_same_or_derived<std::forward_iterator_tag,T>
|
||||
>
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
#else
|
||||
template <class Tag, class T>
|
||||
struct is_tag;
|
||||
#endif
|
||||
|
||||
// Generate specializations which will allow us to find
|
||||
// null_category_tag as a minimum old-style category for new-style
|
||||
// iterators which don't have an actual old-style category. We
|
||||
// need that so there is a valid base class for all new-style
|
||||
// iterators.
|
||||
#define BOOST_OLD_ITERATOR_CATEGORY(category) \
|
||||
template <> \
|
||||
struct is_tag <detail::null_category_tag, std::category> \
|
||||
: mpl::true_ {};
|
||||
|
||||
BOOST_OLD_ITERATOR_CATEGORY(input_iterator_tag)
|
||||
BOOST_OLD_ITERATOR_CATEGORY(output_iterator_tag)
|
||||
BOOST_OLD_ITERATOR_CATEGORY(forward_iterator_tag)
|
||||
BOOST_OLD_ITERATOR_CATEGORY(bidirectional_iterator_tag)
|
||||
BOOST_OLD_ITERATOR_CATEGORY(random_access_iterator_tag)
|
||||
#undef BOOST_OLD_ITERATOR_CATEGORY
|
||||
|
||||
template <>
|
||||
struct is_tag<detail::input_output_iterator_tag,std::forward_iterator_tag>
|
||||
: mpl::true_
|
||||
{
|
||||
};
|
||||
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <class T>
|
||||
struct is_tag<T,T> : mpl::true_
|
||||
{};
|
||||
|
||||
# ifdef BOOST_NO_IS_CONVERTIBLE
|
||||
// Workarounds for CWPro7 which can't detect derivation at
|
||||
// compile-time.
|
||||
|
||||
// Fact of life: we can only detect tag refinement relationships
|
||||
// among predefined tags.
|
||||
//
|
||||
// Algorithm:
|
||||
// is_tag(T,U) ->
|
||||
// T == U
|
||||
// || (exists d in derived_from(T) such that is_tag(d, U))
|
||||
//
|
||||
// T == U case is handled above
|
||||
|
||||
// false by default
|
||||
template <class Tag, class T>
|
||||
struct is_tag_impl : mpl::false_
|
||||
{};
|
||||
|
||||
// The generalized template dispatches to is_tag_impl because
|
||||
// is_tag<T,T> and is_tag<some_tag,T> are equally specialized.
|
||||
// This technique simulates making is_tag<T,T> more-specialized.
|
||||
template <class Tag, class T>
|
||||
struct is_tag
|
||||
: is_tag_impl<Tag, T>
|
||||
{};
|
||||
|
||||
# define BOOST_ITERATOR_DERIVED_TAG1(base, derived) \
|
||||
BOOST_ITERATOR_DERIVED_TAG1_AUX(base, _, derived)
|
||||
|
||||
# define BOOST_ITERATOR_DERIVED_TAG1_AUX(base, underscore, derived) \
|
||||
template<class T> \
|
||||
struct is_tag_impl<base##underscore##tag, T> \
|
||||
: is_tag<derived##underscore##tag, T> \
|
||||
{ \
|
||||
};
|
||||
|
||||
// Old-style tag relations
|
||||
template<class T>
|
||||
struct is_tag_impl<detail::null_category_tag, T>
|
||||
: mpl::or_<
|
||||
is_tag<std::output_iterator_tag, T>
|
||||
, is_tag<std::input_iterator_tag, T>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
BOOST_ITERATOR_DERIVED_TAG1(std::output_iterator, detail::input_output_iterator)
|
||||
BOOST_ITERATOR_DERIVED_TAG1(std::input_iterator, detail::input_output_iterator)
|
||||
BOOST_ITERATOR_DERIVED_TAG1(detail::input_output_iterator, std::forward_iterator)
|
||||
BOOST_ITERATOR_DERIVED_TAG1(std::forward_iterator, std::bidirectional_iterator)
|
||||
BOOST_ITERATOR_DERIVED_TAG1(std::bidirectional_iterator, std::random_access_iterator)
|
||||
|
||||
// Access tag relations
|
||||
BOOST_ITERATOR_DERIVED_TAG1(readable_lvalue_iterator, writable_lvalue_iterator)
|
||||
BOOST_ITERATOR_DERIVED_TAG1(swappable_iterator, readable_writable_iterator)
|
||||
BOOST_ITERATOR_DERIVED_TAG1(readable_writable_iterator, writable_lvalue_iterator)
|
||||
|
||||
template<class T>
|
||||
struct is_tag_impl<readable_iterator_tag, T>
|
||||
: mpl::or_<
|
||||
is_tag<readable_lvalue_iterator_tag, T>
|
||||
, is_tag<readable_writable_iterator_tag, T>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
BOOST_ITERATOR_DERIVED_TAG1(writable_iterator, readable_writable_iterator)
|
||||
|
||||
// Traversal tag relations
|
||||
BOOST_ITERATOR_DERIVED_TAG1(bidirectional_traversal, random_access_traversal)
|
||||
BOOST_ITERATOR_DERIVED_TAG1(forward_traversal, bidirectional_traversal)
|
||||
BOOST_ITERATOR_DERIVED_TAG1(single_pass_iterator, forward_traversal)
|
||||
BOOST_ITERATOR_DERIVED_TAG1(incrementable_iterator, single_pass_iterator)
|
||||
|
||||
# endif // BOOST_NO_IS_CONVERTIBLE workarounds
|
||||
|
||||
#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION case
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// Returns the minimum category type or error_type
|
||||
// if T1 and T2 are unrelated.
|
||||
@@ -446,19 +280,18 @@ namespace boost {
|
||||
//
|
||||
//
|
||||
template <class T1, class T2>
|
||||
struct minimum_category :
|
||||
#ifndef BOOST_NO_IS_CONVERTIBLE
|
||||
mpl::if_< is_base_or_same< T1, T2 >,
|
||||
T1,
|
||||
mpl::if_< is_base_or_same< T2, T1 >,
|
||||
T2,
|
||||
error_type > >
|
||||
#else
|
||||
minimum_category_select< minimum_return_category<T1, T2>,
|
||||
minimum_traversal_category<T1, T2> >
|
||||
#endif
|
||||
struct minimum_category
|
||||
: mpl::apply_if<
|
||||
is_tag<T1,T2>
|
||||
, mpl::identity<T1>
|
||||
, mpl::if_<
|
||||
is_tag<T2, T1>
|
||||
, T2
|
||||
, error_type
|
||||
>
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
@@ -69,7 +69,7 @@ namespace boost
|
||||
class Return>
|
||||
struct enable_if
|
||||
# if !defined(BOOST_NO_SFINAE) && !defined(BOOST_NO_IS_CONVERTIBLE)
|
||||
: enabled<Cond::value>::template base<Return>
|
||||
: enabled<(Cond::value)>::template base<Return>
|
||||
# else
|
||||
: mpl::identity<Return>
|
||||
# endif
|
||||
|
||||
Reference in New Issue
Block a user