mirror of
https://github.com/boostorg/iterator.git
synced 2025-05-12 05:51:37 +00:00
Moved concept checks into a separate class, which makes MSVC better at dealing with them
[SVN r12255]
This commit is contained in:
parent
ebcb4d861a
commit
57251d58cc
@ -12,6 +12,9 @@
|
|||||||
//
|
//
|
||||||
// Revision History:
|
// Revision History:
|
||||||
|
|
||||||
|
// 08 Jan 2001 David Abrahams
|
||||||
|
// Moved concept checks into a separate class, which makes MSVC
|
||||||
|
// better at dealing with them.
|
||||||
// 07 Jan 2001 David Abrahams
|
// 07 Jan 2001 David Abrahams
|
||||||
// Choose proxy for operator->() only if the reference type is not a reference.
|
// Choose proxy for operator->() only if the reference type is not a reference.
|
||||||
// Updated workarounds for __MWERKS__ == 0x2406
|
// Updated workarounds for __MWERKS__ == 0x2406
|
||||||
@ -554,7 +557,7 @@ namespace detail {
|
|||||||
// An associative list is a list of key-value pairs. The list is
|
// An associative list is a list of key-value pairs. The list is
|
||||||
// built out of cons_type's and is terminated by end_of_list.
|
// built out of cons_type's and is terminated by end_of_list.
|
||||||
|
|
||||||
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) || defined(__BORLANDC__)
|
# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) || defined(__BORLANDC__)
|
||||||
template <class AssocList, class Key>
|
template <class AssocList, class Key>
|
||||||
struct find_param;
|
struct find_param;
|
||||||
|
|
||||||
@ -583,7 +586,7 @@ namespace detail {
|
|||||||
typedef typename find_param_helper1<AssocList>::type select1;
|
typedef typename find_param_helper1<AssocList>::type select1;
|
||||||
typedef typename select1::template select<AssocList, Key>::type type;
|
typedef typename select1::template select<AssocList, Key>::type type;
|
||||||
};
|
};
|
||||||
#else
|
# else
|
||||||
template <class AssocList, class Key> struct find_param;
|
template <class AssocList, class Key> struct find_param;
|
||||||
|
|
||||||
template <class Key>
|
template <class Key>
|
||||||
@ -600,7 +603,7 @@ namespace detail {
|
|||||||
struct find_param<detail::cons_type< detail::cons_type<Key1, Value>, Rest>, Key2> {
|
struct find_param<detail::cons_type< detail::cons_type<Key1, Value>, Rest>, Key2> {
|
||||||
typedef typename find_param<Rest, Key2>::type type;
|
typedef typename find_param<Rest, Key2>::type type;
|
||||||
};
|
};
|
||||||
#endif
|
# endif
|
||||||
|
|
||||||
struct make_named_arg {
|
struct make_named_arg {
|
||||||
template <class Key, class Value>
|
template <class Key, class Value>
|
||||||
@ -617,26 +620,26 @@ namespace detail {
|
|||||||
enum { value = is_convertible<Value, named_template_param_base>::value };
|
enum { value = is_convertible<Value, named_template_param_base>::value };
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(__MWERKS__) && __MWERKS__ <= 0x2406 // workaround for broken is_convertible implementation
|
# if defined(__MWERKS__) && __MWERKS__ <= 0x2406 // workaround for broken is_convertible implementation
|
||||||
template <class T> struct is_named_parameter<value_type_is<T> > { enum { value = true }; };
|
template <class T> struct is_named_parameter<value_type_is<T> > { enum { value = true }; };
|
||||||
template <class T> struct is_named_parameter<reference_is<T> > { enum { value = true }; };
|
template <class T> struct is_named_parameter<reference_is<T> > { enum { value = true }; };
|
||||||
template <class T> struct is_named_parameter<pointer_is<T> > { enum { value = true }; };
|
template <class T> struct is_named_parameter<pointer_is<T> > { enum { value = true }; };
|
||||||
template <class T> struct is_named_parameter<difference_type_is<T> > { enum { value = true }; };
|
template <class T> struct is_named_parameter<difference_type_is<T> > { enum { value = true }; };
|
||||||
template <class T> struct is_named_parameter<iterator_category_is<T> > { enum { value = true }; };
|
template <class T> struct is_named_parameter<iterator_category_is<T> > { enum { value = true }; };
|
||||||
#endif
|
# endif
|
||||||
|
|
||||||
template <class Key, class Value>
|
template <class Key, class Value>
|
||||||
struct make_arg {
|
struct make_arg {
|
||||||
#ifdef __BORLANDC__
|
# ifdef __BORLANDC__
|
||||||
// Borland C++ doesn't like the extra indirection of is_named_parameter
|
// Borland C++ doesn't like the extra indirection of is_named_parameter
|
||||||
typedef typename
|
typedef typename
|
||||||
if_true<(is_convertible<Value,named_template_param_base>::value)>::
|
if_true<(is_convertible<Value,named_template_param_base>::value)>::
|
||||||
template then<make_named_arg, make_key_value>::type Make;
|
template then<make_named_arg, make_key_value>::type Make;
|
||||||
#else
|
# else
|
||||||
enum { is_named = is_named_parameter<Value>::value };
|
enum { is_named = is_named_parameter<Value>::value };
|
||||||
typedef typename if_true<(is_named)>::template
|
typedef typename if_true<(is_named)>::template
|
||||||
then<make_named_arg, make_key_value>::type Make;
|
then<make_named_arg, make_key_value>::type Make;
|
||||||
#endif
|
# endif
|
||||||
typedef typename Make::template select<Key, Value>::type type;
|
typedef typename Make::template select<Key, Value>::type type;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -727,6 +730,29 @@ namespace detail {
|
|||||||
difference_type, pointer, reference> type;
|
difference_type, pointer, reference> type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// This is really a partial concept check for iterators. Should it
|
||||||
|
// be moved or done differently?
|
||||||
|
template <class Category, class Value, class Difference, class Pointer, class Reference>
|
||||||
|
struct validator
|
||||||
|
{
|
||||||
|
BOOST_STATIC_CONSTANT(
|
||||||
|
bool, is_input_or_output_iter
|
||||||
|
= (boost::is_convertible<Category*,std::input_iterator_tag*>::value
|
||||||
|
| boost::is_convertible<Category*,std::output_iterator_tag*>::value));
|
||||||
|
|
||||||
|
// Iterators should satisfy one of the known categories
|
||||||
|
BOOST_STATIC_ASSERT(is_input_or_output_iter);
|
||||||
|
|
||||||
|
// Iterators >= ForwardIterator must produce real references
|
||||||
|
// as required by the C++ standard requirements in Table 74.
|
||||||
|
BOOST_STATIC_CONSTANT(
|
||||||
|
bool, forward_iter_with_real_reference
|
||||||
|
= ((!boost::is_convertible<Category*,std::forward_iterator_tag*>::value)
|
||||||
|
| boost::is_same<Reference,Value&>::value
|
||||||
|
| boost::is_same<Reference,typename add_const<Value>::type&>::value));
|
||||||
|
|
||||||
|
BOOST_STATIC_ASSERT(forward_iter_with_real_reference);
|
||||||
|
};
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
|
|
||||||
@ -738,8 +764,6 @@ namespace detail {
|
|||||||
# define BOOST_ARG_DEPENDENT_TYPENAME
|
# define BOOST_ARG_DEPENDENT_TYPENAME
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
template <class T> struct undefined;
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
//iterator_adaptor - Adapts a generic piece of data as an iterator. Adaptation
|
//iterator_adaptor - Adapts a generic piece of data as an iterator. Adaptation
|
||||||
// is especially easy if the data being adapted is itself an iterator
|
// is especially easy if the data being adapted is itself an iterator
|
||||||
@ -800,30 +824,19 @@ struct iterator_adaptor :
|
|||||||
typedef Policies policies_type;
|
typedef Policies policies_type;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BOOST_STATIC_CONSTANT(bool, is_input_or_output_iter
|
typedef detail::validator<
|
||||||
= (boost::is_convertible<iterator_category*,std::input_iterator_tag*>::value
|
iterator_category,value_type,difference_type,pointer,reference
|
||||||
| boost::is_convertible<iterator_category*,std::output_iterator_tag*>::value));
|
> concept_check;
|
||||||
|
|
||||||
// Iterators should satisfy one of the known categories
|
|
||||||
BOOST_STATIC_ASSERT(is_input_or_output_iter);
|
|
||||||
|
|
||||||
// Iterators >= ForwardIterator must produce real references
|
|
||||||
// as required by the C++ standard requirements in Table 74.
|
|
||||||
BOOST_STATIC_CONSTANT(bool, forward_iter_with_real_reference
|
|
||||||
= ((!boost::is_convertible<iterator_category*,std::forward_iterator_tag*>::value)
|
|
||||||
| boost::is_same<reference,value_type&>::value
|
|
||||||
| boost::is_same<reference,const value_type&>::value));
|
|
||||||
|
|
||||||
// This check gives incorrect results in iter_traits_gen_test.cpp
|
|
||||||
BOOST_STATIC_ASSERT(forward_iter_with_real_reference);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
iterator_adaptor() { }
|
iterator_adaptor()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
explicit
|
explicit
|
||||||
iterator_adaptor(const Base& it, const Policies& p = Policies())
|
iterator_adaptor(const Base& it, const Policies& p = Policies())
|
||||||
: m_iter_p(it, p) {
|
: m_iter_p(it, p) {
|
||||||
policies().initialize(base());
|
policies().initialize(base());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Iter2, class Value2, class Pointer2, class Reference2>
|
template <class Iter2, class Value2, class Pointer2, class Reference2>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user