mirror of
https://github.com/boostorg/concept_check.git
synced 2025-07-30 20:47:34 +02:00
moved from pending to boost/
[SVN r8412]
This commit is contained in:
599
include/boost/concept_archetype.hpp
Normal file
599
include/boost/concept_archetype.hpp
Normal file
@ -0,0 +1,599 @@
|
||||
//
|
||||
// (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify,
|
||||
// sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
//
|
||||
#ifndef BOOST_CONCEPT_ARCHETYPES_HPP
|
||||
#define BOOST_CONCEPT_ARCHETYPES_HPP
|
||||
|
||||
#include <iterator>
|
||||
#include <functional>
|
||||
|
||||
namespace boost {
|
||||
|
||||
//===========================================================================
|
||||
// Basic Archetype Classes
|
||||
|
||||
namespace detail {
|
||||
class dummy_constructor { };
|
||||
}
|
||||
static detail::dummy_constructor dummy_cons;
|
||||
|
||||
// A type that models no concept. The template parameter
|
||||
// is only there so that null_archetype types can be created
|
||||
// that have different type.
|
||||
template <class T = int>
|
||||
class null_archetype {
|
||||
private:
|
||||
null_archetype() { }
|
||||
null_archetype(const null_archetype&) { }
|
||||
null_archetype& operator=(const null_archetype&) { return *this; }
|
||||
public:
|
||||
null_archetype(detail::dummy_constructor) { }
|
||||
template <class TT>
|
||||
friend void dummy_friend(); // just to avoid warnings
|
||||
};
|
||||
|
||||
// This is a helper class that provides a way to get a reference to
|
||||
// an object.
|
||||
template <class T>
|
||||
class static_object {
|
||||
public:
|
||||
static T& get() {
|
||||
detail::dummy_constructor d;
|
||||
static T x(d);
|
||||
return x;
|
||||
}
|
||||
};
|
||||
template <>
|
||||
class static_object<bool> {
|
||||
public:
|
||||
static bool& get() {
|
||||
static bool b;
|
||||
return b;
|
||||
}
|
||||
};
|
||||
template <>
|
||||
class static_object<int> {
|
||||
public:
|
||||
static int& get() {
|
||||
static int b;
|
||||
return b;
|
||||
}
|
||||
};
|
||||
|
||||
template <class Base = null_archetype<> >
|
||||
class default_constructible_archetype : public Base {
|
||||
public:
|
||||
default_constructible_archetype() : Base(dummy_cons) { }
|
||||
default_constructible_archetype(detail::dummy_constructor x) : Base(x) { }
|
||||
};
|
||||
|
||||
template <class Base = null_archetype<> >
|
||||
class assignable_archetype : public Base {
|
||||
assignable_archetype() { }
|
||||
assignable_archetype(const assignable_archetype&) { }
|
||||
public:
|
||||
assignable_archetype& operator=(const assignable_archetype&) {
|
||||
return *this;
|
||||
}
|
||||
assignable_archetype(detail::dummy_constructor x) : Base(x) { }
|
||||
};
|
||||
|
||||
template <class Base = null_archetype<> >
|
||||
class copy_constructible_archetype : public Base {
|
||||
public:
|
||||
copy_constructible_archetype() : Base(dummy_cons) { }
|
||||
copy_constructible_archetype(const copy_constructible_archetype&)
|
||||
: Base(dummy_cons) { }
|
||||
copy_constructible_archetype(detail::dummy_constructor x) : Base(x) { }
|
||||
};
|
||||
|
||||
template <class Base = null_archetype<> >
|
||||
class sgi_assignable_archetype : public Base {
|
||||
public:
|
||||
sgi_assignable_archetype(const sgi_assignable_archetype&)
|
||||
: Base(dummy_cons) { }
|
||||
sgi_assignable_archetype& operator=(const sgi_assignable_archetype&) {
|
||||
return *this;
|
||||
}
|
||||
sgi_assignable_archetype(const detail::dummy_constructor& x) : Base(x) { }
|
||||
};
|
||||
|
||||
struct default_archetype_base {
|
||||
default_archetype_base(detail::dummy_constructor x) { }
|
||||
};
|
||||
|
||||
// Careful, don't use same type for T and Base. That results in the
|
||||
// conversion operator being invalid. Since T is often
|
||||
// null_archetype, can't use null_archetype for Base.
|
||||
template <class T, class Base = default_archetype_base>
|
||||
class convertible_to_archetype : public Base {
|
||||
private:
|
||||
convertible_to_archetype() { }
|
||||
convertible_to_archetype(const convertible_to_archetype& ) { }
|
||||
convertible_to_archetype& operator=(const convertible_to_archetype&)
|
||||
{ return *this; }
|
||||
public:
|
||||
convertible_to_archetype(detail::dummy_constructor x) : Base(x) { }
|
||||
operator const T&() const { return static_object<T>::get(); }
|
||||
};
|
||||
|
||||
template <class T, class Base = default_archetype_base>
|
||||
class convertible_from_archetype : public Base {
|
||||
private:
|
||||
convertible_from_archetype() { }
|
||||
convertible_from_archetype(const convertible_from_archetype& ) { }
|
||||
convertible_from_archetype& operator=(const convertible_from_archetype&)
|
||||
{ return *this; }
|
||||
public:
|
||||
convertible_from_archetype(detail::dummy_constructor x) : Base(x) { }
|
||||
convertible_from_archetype(const T&) { }
|
||||
convertible_from_archetype& operator=(const T&)
|
||||
{ return *this; }
|
||||
};
|
||||
|
||||
class boolean_archetype {
|
||||
public:
|
||||
boolean_archetype(const boolean_archetype&) { }
|
||||
operator bool() const { return true; }
|
||||
boolean_archetype(detail::dummy_constructor x) { }
|
||||
private:
|
||||
boolean_archetype() { }
|
||||
boolean_archetype& operator=(const boolean_archetype&) { return *this; }
|
||||
};
|
||||
|
||||
template <class Base = null_archetype<> >
|
||||
class equality_comparable_archetype : public Base {
|
||||
public:
|
||||
equality_comparable_archetype(detail::dummy_constructor x) : Base(x) { }
|
||||
};
|
||||
template <class Base>
|
||||
boolean_archetype
|
||||
operator==(const equality_comparable_archetype<Base>&,
|
||||
const equality_comparable_archetype<Base>&)
|
||||
{ return boolean_archetype(dummy_cons); }
|
||||
template <class Base>
|
||||
boolean_archetype
|
||||
operator!=(const equality_comparable_archetype<Base>&,
|
||||
const equality_comparable_archetype<Base>&)
|
||||
{ return boolean_archetype(dummy_cons); }
|
||||
|
||||
|
||||
template <class Base = null_archetype<> >
|
||||
class equality_comparable2_first_archetype : public Base {
|
||||
public:
|
||||
equality_comparable2_first_archetype(detail::dummy_constructor x)
|
||||
: Base(x) { }
|
||||
};
|
||||
template <class Base = null_archetype<> >
|
||||
class equality_comparable2_second_archetype : public Base {
|
||||
public:
|
||||
equality_comparable2_second_archetype(detail::dummy_constructor x)
|
||||
: Base(x) { }
|
||||
};
|
||||
template <class Base1, class Base2>
|
||||
boolean_archetype
|
||||
operator==(const equality_comparable2_first_archetype<Base1>&,
|
||||
const equality_comparable2_second_archetype<Base2>&)
|
||||
{ return boolean_archetype(dummy_cons); }
|
||||
template <class Base1, class Base2>
|
||||
boolean_archetype
|
||||
operator!=(const equality_comparable2_first_archetype<Base1>&,
|
||||
const equality_comparable2_second_archetype<Base2>&)
|
||||
{ return boolean_archetype(dummy_cons); }
|
||||
|
||||
|
||||
template <class Base = null_archetype<> >
|
||||
class less_than_comparable_archetype : public Base {
|
||||
public:
|
||||
less_than_comparable_archetype(detail::dummy_constructor x) : Base(x) { }
|
||||
};
|
||||
template <class Base>
|
||||
boolean_archetype
|
||||
operator<(const less_than_comparable_archetype<Base>&,
|
||||
const less_than_comparable_archetype<Base>&)
|
||||
{ return boolean_archetype(dummy_cons); }
|
||||
|
||||
|
||||
|
||||
template <class Base = null_archetype<> >
|
||||
class comparable_archetype : public Base {
|
||||
public:
|
||||
comparable_archetype(detail::dummy_constructor x) : Base(x) { }
|
||||
};
|
||||
template <class Base>
|
||||
boolean_archetype
|
||||
operator<(const comparable_archetype<Base>&,
|
||||
const comparable_archetype<Base>&)
|
||||
{ return boolean_archetype(dummy_cons); }
|
||||
template <class Base>
|
||||
boolean_archetype
|
||||
operator<=(const comparable_archetype<Base>&,
|
||||
const comparable_archetype<Base>&)
|
||||
{ return boolean_archetype(dummy_cons); }
|
||||
template <class Base>
|
||||
boolean_archetype
|
||||
operator>(const comparable_archetype<Base>&,
|
||||
const comparable_archetype<Base>&)
|
||||
{ return boolean_archetype(dummy_cons); }
|
||||
template <class Base>
|
||||
boolean_archetype
|
||||
operator>=(const comparable_archetype<Base>&,
|
||||
const comparable_archetype<Base>&)
|
||||
{ return boolean_archetype(dummy_cons); }
|
||||
|
||||
|
||||
// The purpose of the optags is so that one can specify
|
||||
// exactly which types the operator< is defined between.
|
||||
// This is useful for allowing the operations:
|
||||
//
|
||||
// A a; B b;
|
||||
// a < b
|
||||
// b < a
|
||||
//
|
||||
// without also allowing the combinations:
|
||||
//
|
||||
// a < a
|
||||
// b < b
|
||||
//
|
||||
struct optag1 { };
|
||||
struct optag2 { };
|
||||
struct optag3 { };
|
||||
|
||||
#define BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(OP, NAME) \
|
||||
template <class Base = null_archetype<>, class Tag = optag1 > \
|
||||
class NAME##_first_archetype : public Base { \
|
||||
public: \
|
||||
NAME##_first_archetype(detail::dummy_constructor x) : Base(x) { } \
|
||||
}; \
|
||||
\
|
||||
template <class Base = null_archetype<>, class Tag = optag1 > \
|
||||
class NAME##_second_archetype : public Base { \
|
||||
public: \
|
||||
NAME##_second_archetype(detail::dummy_constructor x) : Base(x) { } \
|
||||
}; \
|
||||
\
|
||||
template <class BaseFirst, class BaseSecond, class Tag> \
|
||||
boolean_archetype \
|
||||
operator OP (const NAME##_first_archetype<BaseFirst, Tag>&, \
|
||||
const NAME##_second_archetype<BaseSecond, Tag>&) \
|
||||
{ \
|
||||
return boolean_archetype(dummy_cons); \
|
||||
}
|
||||
|
||||
BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(==, equal_op)
|
||||
BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(!=, not_equal_op)
|
||||
BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(<, less_than_op)
|
||||
BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(<=, less_equal_op)
|
||||
BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(>, greater_than_op)
|
||||
BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(>=, greater_equal_op)
|
||||
|
||||
#define BOOST_DEFINE_OPERATOR_ARCHETYPE(OP, NAME) \
|
||||
template <class Base = null_archetype<> > \
|
||||
class NAME##_archetype : public Base { \
|
||||
public: \
|
||||
NAME##_archetype(detail::dummy_constructor x) : Base(x) { } \
|
||||
NAME##_archetype(const NAME##_archetype&) \
|
||||
: Base(dummy_cons) { } \
|
||||
NAME##_archetype& operator=(const NAME##_archetype&) { return *this; } \
|
||||
}; \
|
||||
template <class Base> \
|
||||
NAME##_archetype<Base> \
|
||||
operator OP (const NAME##_archetype<Base>&,\
|
||||
const NAME##_archetype<Base>&) \
|
||||
{ return NAME##_archetype<Base>(dummy_cons); }
|
||||
|
||||
BOOST_DEFINE_OPERATOR_ARCHETYPE(+, addable)
|
||||
BOOST_DEFINE_OPERATOR_ARCHETYPE(-, subtractable)
|
||||
BOOST_DEFINE_OPERATOR_ARCHETYPE(*, multipliable)
|
||||
BOOST_DEFINE_OPERATOR_ARCHETYPE(/, dividable)
|
||||
BOOST_DEFINE_OPERATOR_ARCHETYPE(%, modable)
|
||||
|
||||
// As is, these are useless because of the return type.
|
||||
// Need to invent a better way...
|
||||
#define BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(OP, NAME) \
|
||||
template <class Return, class Base = null_archetype<> > \
|
||||
class NAME##_first_archetype : public Base { \
|
||||
public: \
|
||||
NAME##_first_archetype(detail::dummy_constructor x) : Base(x) { } \
|
||||
}; \
|
||||
\
|
||||
template <class Return, class Base = null_archetype<> > \
|
||||
class NAME##_second_archetype : public Base { \
|
||||
public: \
|
||||
NAME##_second_archetype(detail::dummy_constructor x) : Base(x) { } \
|
||||
}; \
|
||||
\
|
||||
template <class Return, class BaseFirst, class BaseSecond> \
|
||||
Return \
|
||||
operator OP (const NAME##_first_archetype<Return, BaseFirst>&, \
|
||||
const NAME##_second_archetype<Return, BaseSecond>&) \
|
||||
{ \
|
||||
return Return(dummy_cons); \
|
||||
}
|
||||
|
||||
BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(+, plus_op)
|
||||
BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(*, time_op)
|
||||
BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(/, divide_op)
|
||||
BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(-, subtract_op)
|
||||
BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(%, mod_op)
|
||||
|
||||
//===========================================================================
|
||||
// Function Object Archetype Classes
|
||||
|
||||
template <class Return>
|
||||
class generator_archetype {
|
||||
public:
|
||||
const Return& operator()() {
|
||||
return static_object<Return>::get();
|
||||
}
|
||||
};
|
||||
|
||||
class void_generator_archetype {
|
||||
public:
|
||||
void operator()() { }
|
||||
};
|
||||
|
||||
template <class Arg, class Return>
|
||||
class unary_function_archetype {
|
||||
private:
|
||||
unary_function_archetype() { }
|
||||
public:
|
||||
unary_function_archetype(detail::dummy_constructor) { }
|
||||
const Return& operator()(const Arg&) {
|
||||
return static_object<Return>::get();
|
||||
}
|
||||
};
|
||||
|
||||
template <class Arg1, class Arg2, class Return>
|
||||
class binary_function_archetype {
|
||||
private:
|
||||
binary_function_archetype() { }
|
||||
public:
|
||||
binary_function_archetype(detail::dummy_constructor) { }
|
||||
const Return& operator()(const Arg1&, const Arg2&) {
|
||||
return static_object<Return>::get();
|
||||
}
|
||||
};
|
||||
|
||||
template <class Arg>
|
||||
class unary_predicate_archetype {
|
||||
typedef boolean_archetype Return;
|
||||
unary_predicate_archetype() { }
|
||||
public:
|
||||
unary_predicate_archetype(detail::dummy_constructor) { }
|
||||
const Return& operator()(const Arg&) {
|
||||
return static_object<Return>::get();
|
||||
}
|
||||
};
|
||||
|
||||
template <class Arg1, class Arg2, class Base = null_archetype<> >
|
||||
class binary_predicate_archetype {
|
||||
typedef boolean_archetype Return;
|
||||
binary_predicate_archetype() { }
|
||||
public:
|
||||
binary_predicate_archetype(detail::dummy_constructor) { }
|
||||
const Return& operator()(const Arg1&, const Arg2&) {
|
||||
return static_object<Return>::get();
|
||||
}
|
||||
};
|
||||
|
||||
template <class Arg1, class Arg2>
|
||||
class const_binary_predicate_archetype {
|
||||
typedef boolean_archetype Return;
|
||||
const_binary_predicate_archetype() { }
|
||||
public:
|
||||
const_binary_predicate_archetype(detail::dummy_constructor) { }
|
||||
const Return& operator()(const Arg1&, const Arg2&) const {
|
||||
return static_object<Return>::get();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//===========================================================================
|
||||
// Iterator Archetype Classes
|
||||
|
||||
template <class T>
|
||||
struct input_proxy {
|
||||
operator const T&() { return static_object<T>::get(); }
|
||||
};
|
||||
template <class T>
|
||||
class trivial_iterator_archetype
|
||||
{
|
||||
typedef trivial_iterator_archetype self;
|
||||
public:
|
||||
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
typedef T value_type;
|
||||
typedef void reference;
|
||||
typedef void pointer;
|
||||
typedef void difference_type;
|
||||
typedef void iterator_category;
|
||||
#endif
|
||||
trivial_iterator_archetype() { }
|
||||
self& operator=(const self&) { return *this; }
|
||||
bool operator==(const self&) const { return true; }
|
||||
bool operator!=(const self&) const { return true; }
|
||||
input_proxy<T> operator*() const { return input_proxy<T>(); }
|
||||
};
|
||||
} // namespace boost
|
||||
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
namespace std {
|
||||
template <class T>
|
||||
struct iterator_traits< boost::trivial_iterator_archetype<T> >
|
||||
{
|
||||
typedef T value_type;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
template <class T>
|
||||
struct input_output_proxy {
|
||||
input_output_proxy<T>& operator=(const T&) { return *this; }
|
||||
operator const T&() { return static_object<T>::get(); }
|
||||
};
|
||||
template <class T>
|
||||
class mutable_trivial_iterator_archetype
|
||||
{
|
||||
typedef mutable_trivial_iterator_archetype self;
|
||||
public:
|
||||
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
typedef T value_type;
|
||||
typedef void reference;
|
||||
typedef void pointer;
|
||||
typedef void difference_type;
|
||||
typedef void iterator_category;
|
||||
#endif
|
||||
mutable_trivial_iterator_archetype() { }
|
||||
self& operator=(const self&) { return *this; }
|
||||
bool operator==(const self&) const { return true; }
|
||||
bool operator!=(const self&) const { return true; }
|
||||
input_output_proxy<T> operator*() const { return input_output_proxy<T>(); }
|
||||
};
|
||||
} // namespace boost
|
||||
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
namespace std {
|
||||
template <class T>
|
||||
struct iterator_traits< boost::mutable_trivial_iterator_archetype<T> >
|
||||
{
|
||||
typedef T value_type;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
template <class T>
|
||||
class input_iterator_archetype
|
||||
{
|
||||
public:
|
||||
typedef input_iterator_archetype self;
|
||||
public:
|
||||
typedef std::input_iterator_tag iterator_category;
|
||||
typedef T value_type;
|
||||
typedef const T& reference;
|
||||
typedef const T* pointer;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
input_iterator_archetype() { }
|
||||
self& operator=(const self&) { return *this; }
|
||||
bool operator==(const self&) const { return true; }
|
||||
bool operator!=(const self&) const { return true; }
|
||||
reference operator*() const { return static_object<T>::get(); }
|
||||
self& operator++() { return *this; }
|
||||
self operator++(int) { return *this; }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct output_proxy {
|
||||
output_proxy& operator=(const T&) { return *this; }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class output_iterator_archetype
|
||||
{
|
||||
public:
|
||||
typedef output_iterator_archetype self;
|
||||
public:
|
||||
typedef std::output_iterator_tag iterator_category;
|
||||
typedef output_proxy<T> value_type;
|
||||
typedef output_proxy<T> reference;
|
||||
typedef void pointer;
|
||||
typedef void difference_type;
|
||||
output_iterator_archetype() { }
|
||||
self& operator=(const self&) { return *this; }
|
||||
bool operator==(const self&) const { return true; }
|
||||
bool operator!=(const self&) const { return true; }
|
||||
reference operator*() const { return output_proxy<T>(); }
|
||||
self& operator++() { return *this; }
|
||||
self operator++(int) { return *this; }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class forward_iterator_archetype
|
||||
{
|
||||
public:
|
||||
typedef forward_iterator_archetype self;
|
||||
public:
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
typedef T value_type;
|
||||
typedef T& reference;
|
||||
typedef T* pointer;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
forward_iterator_archetype() { }
|
||||
self& operator=(const self&) { return *this; }
|
||||
bool operator==(const self&) const { return true; }
|
||||
bool operator!=(const self&) const { return true; }
|
||||
reference operator*() const { return static_object<T>::get(); }
|
||||
self& operator++() { return *this; }
|
||||
self operator++(int) { return *this; }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class bidirectional_iterator_archetype
|
||||
{
|
||||
public:
|
||||
typedef bidirectional_iterator_archetype self;
|
||||
public:
|
||||
typedef std::bidirectional_iterator_tag iterator_category;
|
||||
typedef T value_type;
|
||||
typedef T& reference;
|
||||
typedef T* pointer;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
bidirectional_iterator_archetype() { }
|
||||
self& operator=(const self&) { return *this; }
|
||||
bool operator==(const self&) const { return true; }
|
||||
bool operator!=(const self&) const { return true; }
|
||||
reference operator*() const { return static_object<T>::get(); }
|
||||
self& operator++() { return *this; }
|
||||
self operator++(int) { return *this; }
|
||||
self& operator--() { return *this; }
|
||||
self operator--(int) { return *this; }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class random_access_iterator_archetype
|
||||
{
|
||||
public:
|
||||
typedef random_access_iterator_archetype self;
|
||||
public:
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
typedef T value_type;
|
||||
typedef T& reference;
|
||||
typedef T* pointer;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
random_access_iterator_archetype() { }
|
||||
self& operator=(const self&) { return *this; }
|
||||
bool operator==(const self&) const { return true; }
|
||||
bool operator!=(const self&) const { return true; }
|
||||
reference operator*() const { return static_object<T>::get(); }
|
||||
self& operator++() { return *this; }
|
||||
self operator++(int) { return *this; }
|
||||
self& operator--() { return *this; }
|
||||
self operator--(int) { return *this; }
|
||||
reference operator[](difference_type n)
|
||||
{ return static_object<T>::get(); }
|
||||
self& operator+=(difference_type) { return *this; }
|
||||
self& operator-=(difference_type) { return *this; }
|
||||
difference_type operator-(const self&) const
|
||||
{ return difference_type(); }
|
||||
self operator+(difference_type) { return *this; }
|
||||
self operator-(difference_type) { return *this; }
|
||||
bool operator<(const self&) { return true; }
|
||||
bool operator<=(const self&) { return true; }
|
||||
bool operator>(const self&) { return true; }
|
||||
bool operator>=(const self&) { return true; }
|
||||
};
|
||||
template <class T>
|
||||
random_access_iterator_archetype<T>
|
||||
operator+(typename random_access_iterator_archetype<T>::difference_type,
|
||||
const random_access_iterator_archetype<T>& x)
|
||||
{ return x; }
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_CONCEPT_ARCHETYPES_H
|
942
include/boost/concept_check.hpp
Normal file
942
include/boost/concept_check.hpp
Normal file
@ -0,0 +1,942 @@
|
||||
//
|
||||
// (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify,
|
||||
// sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
//
|
||||
#ifndef BOOST_CONCEPT_CHECKS_HPP
|
||||
#define BOOST_CONCEPT_CHECKS_HPP
|
||||
|
||||
#include <iterator>
|
||||
#include <utility>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/pending/limits.hpp>
|
||||
|
||||
#if (__GNUC__) || defined(__KCC) || defined(__ghs) || defined(__MWERKS__)
|
||||
#define BOOST_FPTR &
|
||||
#else
|
||||
#define BOOST_FPTR
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
template <class T> void ignore_unused_variable_warning(const T&) { }
|
||||
|
||||
template <class Concept>
|
||||
void function_requires()
|
||||
{
|
||||
#if !defined(NDEBUG)
|
||||
void (Concept::*x)() = BOOST_FPTR Concept::constraints;
|
||||
ignore_unused_variable_warning(x);
|
||||
#endif
|
||||
}
|
||||
|
||||
// The BOOST_CLASS_REQUIRES macros use function pointers as
|
||||
// template parameters, which VC++ does not support.
|
||||
|
||||
#if defined(BOOST_NO_FUNCTION_PTR_TEMPLATE_PARAMETERS)
|
||||
|
||||
#define BOOST_CLASS_REQUIRES(type_var, concept)
|
||||
#define BOOST_CLASS_REQUIRES2(type_var1, type_var2, concept)
|
||||
#define BOOST_CLASS_REQUIRES3(type_var1, type_var2, type_var3, concept)
|
||||
#define BOOST_CLASS_REQUIRES4(type_var1, type_var2, type_var3, type_var4, concept)
|
||||
|
||||
#else
|
||||
|
||||
#define BOOST_CLASS_REQUIRES(type_var, concept) \
|
||||
typedef void (concept <type_var>::* func##type_var##concept)(); \
|
||||
template <func##type_var##concept _Tp1> \
|
||||
struct concept_checking_##type_var##concept { }; \
|
||||
typedef concept_checking_##type_var##concept< \
|
||||
BOOST_FPTR concept <type_var>::constraints> \
|
||||
concept_checking_typedef_##type_var##concept
|
||||
|
||||
#define BOOST_CLASS_REQUIRES2(type_var1, type_var2, concept) \
|
||||
typedef void (concept <type_var1,type_var2>::* func##type_var1##type_var2##concept)(); \
|
||||
template <func##type_var1##type_var2##concept _Tp1> \
|
||||
struct concept_checking_##type_var1##type_var2##concept { }; \
|
||||
typedef concept_checking_##type_var1##type_var2##concept< \
|
||||
BOOST_FPTR concept <type_var1,type_var2>::constraints> \
|
||||
concept_checking_typedef_##type_var1##type_var2##concept
|
||||
|
||||
#define BOOST_CLASS_REQUIRES3(type_var1, type_var2, type_var3, concept) \
|
||||
typedef void (concept <type_var1,type_var2,type_var3>::* func##type_var1##type_var2##type_var3##concept)(); \
|
||||
template <func##type_var1##type_var2##type_var3##concept _Tp1> \
|
||||
struct concept_checking_##type_var1##type_var2##type_var3##concept { }; \
|
||||
typedef concept_checking_##type_var1##type_var2##type_var3##concept< \
|
||||
BOOST_FPTR concept <type_var1,type_var2,type_var3>::constraints> \
|
||||
concept_checking_typedef_##type_var1##type_var2##type_var3##concept
|
||||
|
||||
#define BOOST_CLASS_REQUIRES4(type_var1, type_var2, type_var3, type_var4, concept) \
|
||||
typedef void (concept <type_var1,type_var2,type_var3,type_var4>::* func##type_var1##type_var2##type_var3##type_var4##concept)(); \
|
||||
template <func##type_var1##type_var2##type_var3##type_var4##concept _Tp1> \
|
||||
struct concept_checking_##type_var1##type_var2##type_var3##type_var4##concept { }; \
|
||||
typedef concept_checking_##type_var1##type_var2##type_var3##type_var4##concept< \
|
||||
BOOST_FPTR concept <type_var1,type_var2,type_var3,type_var4>::constraints> \
|
||||
concept_checking_typedef_##type_var1##type_var2##type_var3##type_var4##concept
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <class T, class U>
|
||||
struct require_same { };
|
||||
|
||||
template <class T>
|
||||
struct require_same<T,T> { typedef T type; };
|
||||
#else
|
||||
// This version does not perform checking, but will not do any harm.
|
||||
template <class T, class U>
|
||||
struct require_same { typedef T type; };
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
struct IntegerConcept {
|
||||
void constraints() {
|
||||
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
errortype_must_be_an_integer_type();
|
||||
#endif
|
||||
}
|
||||
};
|
||||
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <> struct IntegerConcept<short> { void constraints() {} };
|
||||
template <> struct IntegerConcept<unsigned short> { void constraints() {} };
|
||||
template <> struct IntegerConcept<int> { void constraints() {} };
|
||||
template <> struct IntegerConcept<unsigned int> { void constraints() {} };
|
||||
template <> struct IntegerConcept<long> { void constraints() {} };
|
||||
template <> struct IntegerConcept<unsigned long> { void constraints() {} };
|
||||
// etc.
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
struct SignedIntegerConcept {
|
||||
void constraints() {
|
||||
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
errortype_must_be_a_signed_integer_type();
|
||||
#endif
|
||||
}
|
||||
};
|
||||
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <> struct SignedIntegerConcept<short> { void constraints() {} };
|
||||
template <> struct SignedIntegerConcept<int> { void constraints() {} };
|
||||
template <> struct SignedIntegerConcept<long> { void constraints() {} };
|
||||
// etc.
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
struct UnsignedIntegerConcept {
|
||||
void constraints() {
|
||||
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
errortype_must_be_an_unsigned_integer_type();
|
||||
#endif
|
||||
}
|
||||
};
|
||||
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <> struct UnsignedIntegerConcept<unsigned short>
|
||||
{ void constraints() {} };
|
||||
template <> struct UnsignedIntegerConcept<unsigned int>
|
||||
{ void constraints() {} };
|
||||
template <> struct UnsignedIntegerConcept<unsigned long>
|
||||
{ void constraints() {} };
|
||||
// etc.
|
||||
#endif
|
||||
|
||||
//===========================================================================
|
||||
// Basic Concepts
|
||||
|
||||
template <class TT>
|
||||
struct DefaultConstructibleConcept
|
||||
{
|
||||
void constraints() {
|
||||
TT a; // require default constructor
|
||||
ignore_unused_variable_warning(a);
|
||||
}
|
||||
};
|
||||
|
||||
template <class TT>
|
||||
struct AssignableConcept
|
||||
{
|
||||
void constraints() {
|
||||
#if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
|
||||
a = a; // require assignment operator
|
||||
#endif
|
||||
const_constraints(a);
|
||||
}
|
||||
void const_constraints(const TT& b) {
|
||||
#if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
|
||||
a = b; // const required for argument to assignment
|
||||
#endif
|
||||
}
|
||||
TT a;
|
||||
};
|
||||
|
||||
template <class TT>
|
||||
struct CopyConstructibleConcept
|
||||
{
|
||||
void constraints() {
|
||||
TT a(b); // require copy constructor
|
||||
TT* ptr = &a; // require address of operator
|
||||
const_constraints(a);
|
||||
ignore_unused_variable_warning(ptr);
|
||||
}
|
||||
void const_constraints(const TT& a) {
|
||||
TT c(a); // require const copy constructor
|
||||
const TT* ptr = &a; // require const address of operator
|
||||
ignore_unused_variable_warning(c);
|
||||
ignore_unused_variable_warning(ptr);
|
||||
}
|
||||
TT b;
|
||||
};
|
||||
|
||||
// The SGI STL version of Assignable requires copy constructor and operator=
|
||||
template <class TT>
|
||||
struct SGIAssignableConcept
|
||||
{
|
||||
void constraints() {
|
||||
TT b(a);
|
||||
#if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
|
||||
a = a; // require assignment operator
|
||||
#endif
|
||||
const_constraints(a);
|
||||
}
|
||||
void const_constraints(const TT& b) {
|
||||
TT c(b);
|
||||
#if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
|
||||
a = b; // const required for argument to assignment
|
||||
#endif
|
||||
}
|
||||
TT a;
|
||||
};
|
||||
|
||||
template <class X, class Y>
|
||||
struct ConvertibleConcept
|
||||
{
|
||||
void constraints() {
|
||||
Y y = x;
|
||||
ignore_unused_variable_warning(y);
|
||||
}
|
||||
X x;
|
||||
};
|
||||
|
||||
// The C++ standard requirements for many concepts talk about return
|
||||
// types that must be "convertible to bool". The problem with this
|
||||
// requirement is that it leaves the door open for evil proxies that
|
||||
// define things like operator|| with strange return types. Two
|
||||
// possible solutions are:
|
||||
// 1) require the return type to be exactly bool
|
||||
// 2) stay with convertible to bool, and also
|
||||
// specify stuff about all the logical operators.
|
||||
// For now we just test for convertible to bool.
|
||||
template <class TT>
|
||||
void require_boolean_expr(const TT& t) {
|
||||
bool x = t;
|
||||
ignore_unused_variable_warning(x);
|
||||
}
|
||||
|
||||
template <class TT>
|
||||
struct EqualityComparableConcept
|
||||
{
|
||||
void constraints() {
|
||||
require_boolean_expr(a == b);
|
||||
require_boolean_expr(a != b);
|
||||
}
|
||||
TT a, b;
|
||||
};
|
||||
|
||||
template <class TT>
|
||||
struct LessThanComparableConcept
|
||||
{
|
||||
void constraints() {
|
||||
require_boolean_expr(a < b);
|
||||
}
|
||||
TT a, b;
|
||||
};
|
||||
|
||||
// This is equivalent to SGI STL's LessThanComparable.
|
||||
template <class TT>
|
||||
struct ComparableConcept
|
||||
{
|
||||
void constraints() {
|
||||
require_boolean_expr(a < b);
|
||||
require_boolean_expr(a > b);
|
||||
require_boolean_expr(a <= b);
|
||||
require_boolean_expr(a >= b);
|
||||
}
|
||||
TT a, b;
|
||||
};
|
||||
|
||||
#define BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(OP,NAME) \
|
||||
template <class First, class Second> \
|
||||
struct NAME { \
|
||||
void constraints() { (void)constraints_(); } \
|
||||
bool constraints_() { \
|
||||
return a OP b; \
|
||||
} \
|
||||
First a; \
|
||||
Second b; \
|
||||
}
|
||||
|
||||
#define BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(OP,NAME) \
|
||||
template <class Ret, class First, class Second> \
|
||||
struct NAME { \
|
||||
void constraints() { (void)constraints_(); } \
|
||||
Ret constraints_() { \
|
||||
return a OP b; \
|
||||
} \
|
||||
First a; \
|
||||
Second b; \
|
||||
}
|
||||
|
||||
BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(==, EqualOpConcept);
|
||||
BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(!=, NotEqualOpConcept);
|
||||
BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<, LessThanOpConcept);
|
||||
BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<=, LessEqualOpConcept);
|
||||
BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>, GreaterThanOpConcept);
|
||||
BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>=, GreaterEqualOpConcept);
|
||||
|
||||
BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(+, PlusOpConcept);
|
||||
BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(*, TimesOpConcept);
|
||||
BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(/, DivideOpConcept);
|
||||
BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(-, SubtractOpConcept);
|
||||
BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(%, ModOpConcept);
|
||||
|
||||
//===========================================================================
|
||||
// Function Object Concepts
|
||||
|
||||
template <class Func, class Return>
|
||||
struct GeneratorConcept
|
||||
{
|
||||
void constraints() {
|
||||
const Return& r = f(); // require operator() member function
|
||||
}
|
||||
Func f;
|
||||
};
|
||||
|
||||
|
||||
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <class Func>
|
||||
struct GeneratorConcept<Func,void>
|
||||
{
|
||||
void constraints() {
|
||||
f(); // require operator() member function
|
||||
}
|
||||
Func f;
|
||||
};
|
||||
#endif
|
||||
|
||||
template <class Func, class Return, class Arg>
|
||||
struct UnaryFunctionConcept
|
||||
{
|
||||
void constraints() {
|
||||
r = f(arg); // require operator()
|
||||
}
|
||||
Func f;
|
||||
Arg arg;
|
||||
Return r;
|
||||
};
|
||||
|
||||
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <class Func, class Arg>
|
||||
struct UnaryFunctionConcept<Func, void, Arg> {
|
||||
void constraints() {
|
||||
f(arg); // require operator()
|
||||
}
|
||||
Func f;
|
||||
};
|
||||
#endif
|
||||
|
||||
template <class Func, class Return, class First, class Second>
|
||||
struct BinaryFunctionConcept
|
||||
{
|
||||
void constraints() {
|
||||
r = f(first, second); // require operator()
|
||||
}
|
||||
Func f;
|
||||
First first;
|
||||
Second second;
|
||||
Return r;
|
||||
};
|
||||
|
||||
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <class Func, class First, class Second>
|
||||
struct BinaryFunctionConcept<Func, void, First, Second>
|
||||
{
|
||||
void constraints() {
|
||||
f(first, second); // require operator()
|
||||
}
|
||||
Func f;
|
||||
First first;
|
||||
Second second;
|
||||
};
|
||||
#endif
|
||||
|
||||
template <class Func, class Arg>
|
||||
struct UnaryPredicateConcept
|
||||
{
|
||||
void constraints() {
|
||||
require_boolean_expr(f(arg)); // require operator() returning bool
|
||||
}
|
||||
Func f;
|
||||
Arg arg;
|
||||
};
|
||||
|
||||
template <class Func, class First, class Second>
|
||||
struct BinaryPredicateConcept
|
||||
{
|
||||
void constraints() {
|
||||
require_boolean_expr(f(a, b)); // require operator() returning bool
|
||||
}
|
||||
Func f;
|
||||
First a;
|
||||
Second b;
|
||||
};
|
||||
|
||||
// use this when functor is used inside a container class like std::set
|
||||
template <class Func, class First, class Second>
|
||||
struct Const_BinaryPredicateConcept {
|
||||
void constraints() {
|
||||
const_constraints(f);
|
||||
}
|
||||
void const_constraints(const Func& fun) {
|
||||
function_requires<BinaryPredicateConcept<Func, First, Second> >();
|
||||
// operator() must be a const member function
|
||||
require_boolean_expr(fun(a, b));
|
||||
}
|
||||
Func f;
|
||||
First a;
|
||||
Second b;
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
// Iterator Concepts
|
||||
|
||||
template <class TT>
|
||||
struct TrivialIteratorConcept
|
||||
{
|
||||
void constraints() {
|
||||
function_requires< AssignableConcept<TT> >();
|
||||
function_requires< DefaultConstructibleConcept<TT> >();
|
||||
function_requires< EqualityComparableConcept<TT> >();
|
||||
#ifndef BOOST_NO_STD_ITERATOR_TRAITS
|
||||
typedef typename std::iterator_traits<TT>::value_type V;
|
||||
#endif
|
||||
(void)*i; // require dereference operator
|
||||
}
|
||||
TT i;
|
||||
};
|
||||
|
||||
template <class TT>
|
||||
struct Mutable_TrivialIteratorConcept
|
||||
{
|
||||
void constraints() {
|
||||
function_requires< TrivialIteratorConcept<TT> >();
|
||||
*i = *j; // require dereference and assignment
|
||||
}
|
||||
TT i, j;
|
||||
};
|
||||
|
||||
template <class TT>
|
||||
struct InputIteratorConcept
|
||||
{
|
||||
void constraints() {
|
||||
function_requires< TrivialIteratorConcept<TT> >();
|
||||
// require iterator_traits typedef's
|
||||
#ifndef BOOST_NO_STD_ITERATOR_TRAITS
|
||||
typedef typename std::iterator_traits<TT>::difference_type D;
|
||||
function_requires< SignedIntegerConcept<D> >();
|
||||
typedef typename std::iterator_traits<TT>::reference R;
|
||||
typedef typename std::iterator_traits<TT>::pointer P;
|
||||
typedef typename std::iterator_traits<TT>::iterator_category C;
|
||||
function_requires< ConvertibleConcept<
|
||||
typename std::iterator_traits<TT>::iterator_category,
|
||||
std::input_iterator_tag> >();
|
||||
#endif
|
||||
++i; // require preincrement operator
|
||||
i++; // require postincrement operator
|
||||
}
|
||||
TT i;
|
||||
};
|
||||
|
||||
template <class TT, class ValueT>
|
||||
struct OutputIteratorConcept
|
||||
{
|
||||
void constraints() {
|
||||
function_requires< AssignableConcept<TT> >();
|
||||
++i; // require preincrement operator
|
||||
i++; // require postincrement operator
|
||||
*i++ = t; // require postincrement and assignment
|
||||
}
|
||||
TT i, j;
|
||||
ValueT t;
|
||||
};
|
||||
|
||||
template <class TT>
|
||||
struct ForwardIteratorConcept
|
||||
{
|
||||
void constraints() {
|
||||
function_requires< InputIteratorConcept<TT> >();
|
||||
#ifndef BOOST_NO_STD_ITERATOR_TRAITS
|
||||
function_requires< ConvertibleConcept<
|
||||
typename std::iterator_traits<TT>::iterator_category,
|
||||
std::forward_iterator_tag> >();
|
||||
typedef typename std::iterator_traits<TT>::reference reference;
|
||||
reference r = *i;
|
||||
ignore_unused_variable_warning(r);
|
||||
#endif
|
||||
}
|
||||
TT i;
|
||||
};
|
||||
|
||||
template <class TT>
|
||||
struct Mutable_ForwardIteratorConcept
|
||||
{
|
||||
void constraints() {
|
||||
function_requires< ForwardIteratorConcept<TT> >();
|
||||
*i++ = *i; // require postincrement and assignment
|
||||
}
|
||||
TT i;
|
||||
};
|
||||
|
||||
template <class TT>
|
||||
struct BidirectionalIteratorConcept
|
||||
{
|
||||
void constraints() {
|
||||
function_requires< ForwardIteratorConcept<TT> >();
|
||||
#ifndef BOOST_NO_STD_ITERATOR_TRAITS
|
||||
function_requires< ConvertibleConcept<
|
||||
typename std::iterator_traits<TT>::iterator_category,
|
||||
std::bidirectional_iterator_tag> >();
|
||||
#endif
|
||||
--i; // require predecrement operator
|
||||
i--; // require postdecrement operator
|
||||
}
|
||||
TT i;
|
||||
};
|
||||
|
||||
template <class TT>
|
||||
struct Mutable_BidirectionalIteratorConcept
|
||||
{
|
||||
void constraints() {
|
||||
function_requires< BidirectionalIteratorConcept<TT> >();
|
||||
function_requires< Mutable_ForwardIteratorConcept<TT> >();
|
||||
*i-- = *i; // require postdecrement and assignment
|
||||
}
|
||||
TT i;
|
||||
};
|
||||
|
||||
|
||||
template <class TT>
|
||||
struct RandomAccessIteratorConcept
|
||||
{
|
||||
void constraints() {
|
||||
function_requires< BidirectionalIteratorConcept<TT> >();
|
||||
function_requires< ComparableConcept<TT> >();
|
||||
#ifndef BOOST_NO_STD_ITERATOR_TRAITS
|
||||
function_requires< ConvertibleConcept<
|
||||
typename std::iterator_traits<TT>::iterator_category,
|
||||
std::random_access_iterator_tag> >();
|
||||
typedef typename std::iterator_traits<TT>::reference R;
|
||||
#endif
|
||||
|
||||
i += n; // require assignment addition operator
|
||||
i = i + n; i = n + i; // require addition with difference type
|
||||
i -= n; // require assignment subtraction operator
|
||||
i = i - n; // require subtraction with difference type
|
||||
n = i - j; // require difference operator
|
||||
(void)i[n]; // require element access operator
|
||||
}
|
||||
TT a, b;
|
||||
TT i, j;
|
||||
#ifndef BOOST_NO_STD_ITERATOR_TRAITS
|
||||
typename std::iterator_traits<TT>::difference_type n;
|
||||
#else
|
||||
std::ptrdiff_t n;
|
||||
#endif
|
||||
};
|
||||
|
||||
template <class TT>
|
||||
struct Mutable_RandomAccessIteratorConcept
|
||||
{
|
||||
void constraints() {
|
||||
function_requires< RandomAccessIteratorConcept<TT> >();
|
||||
function_requires< Mutable_BidirectionalIteratorConcept<TT> >();
|
||||
i[n] = *i; // require element access and assignment
|
||||
}
|
||||
TT i;
|
||||
#ifndef BOOST_NO_STD_ITERATOR_TRAITS
|
||||
typename std::iterator_traits<TT>::difference_type n;
|
||||
#else
|
||||
std::ptrdiff_t n;
|
||||
#endif
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
// Container Concepts
|
||||
|
||||
template <class Container>
|
||||
struct ContainerConcept
|
||||
{
|
||||
typedef typename Container::value_type value_type;
|
||||
typedef typename Container::difference_type difference_type;
|
||||
typedef typename Container::size_type size_type;
|
||||
typedef typename Container::const_reference const_reference;
|
||||
typedef typename Container::const_pointer const_pointer;
|
||||
typedef typename Container::const_iterator const_iterator;
|
||||
|
||||
void constraints() {
|
||||
function_requires< InputIteratorConcept<const_iterator> >();
|
||||
function_requires< AssignableConcept<Container> >();
|
||||
const Container c;
|
||||
i = c.begin();
|
||||
i = c.end();
|
||||
n = c.size();
|
||||
n = c.max_size();
|
||||
b = c.empty();
|
||||
}
|
||||
bool b;
|
||||
const_iterator i;
|
||||
size_type n;
|
||||
};
|
||||
|
||||
template <class Container>
|
||||
struct Mutable_ContainerConcept
|
||||
{
|
||||
typedef typename Container::value_type value_type;
|
||||
typedef typename Container::reference reference;
|
||||
typedef typename Container::iterator iterator;
|
||||
typedef typename Container::pointer pointer;
|
||||
|
||||
void constraints() {
|
||||
function_requires< ContainerConcept<Container> >();
|
||||
function_requires< AssignableConcept<value_type> >();
|
||||
function_requires< InputIteratorConcept<iterator> >();
|
||||
|
||||
i = c.begin();
|
||||
i = c.end();
|
||||
c.swap(c2);
|
||||
}
|
||||
iterator i;
|
||||
Container c, c2;
|
||||
};
|
||||
|
||||
template <class ForwardContainer>
|
||||
struct ForwardContainerConcept
|
||||
{
|
||||
void constraints() {
|
||||
function_requires< ContainerConcept<ForwardContainer> >();
|
||||
typedef typename ForwardContainer::const_iterator const_iterator;
|
||||
function_requires< ForwardIteratorConcept<const_iterator> >();
|
||||
}
|
||||
};
|
||||
|
||||
template <class ForwardContainer>
|
||||
struct Mutable_ForwardContainerConcept
|
||||
{
|
||||
void constraints() {
|
||||
function_requires< ForwardContainerConcept<ForwardContainer> >();
|
||||
function_requires< Mutable_ContainerConcept<ForwardContainer> >();
|
||||
typedef typename ForwardContainer::iterator iterator;
|
||||
function_requires< Mutable_ForwardIteratorConcept<iterator> >();
|
||||
}
|
||||
};
|
||||
|
||||
template <class ReversibleContainer>
|
||||
struct ReversibleContainerConcept
|
||||
{
|
||||
typedef typename ReversibleContainer::const_iterator const_iterator;
|
||||
typedef typename ReversibleContainer::const_reverse_iterator
|
||||
const_reverse_iterator;
|
||||
|
||||
void constraints() {
|
||||
function_requires< ForwardContainerConcept<ReversibleContainer> >();
|
||||
function_requires< BidirectionalIteratorConcept<const_iterator> >();
|
||||
function_requires< BidirectionalIteratorConcept<const_reverse_iterator> >();
|
||||
|
||||
const ReversibleContainer c;
|
||||
const_reverse_iterator i = c.rbegin();
|
||||
i = c.rend();
|
||||
}
|
||||
};
|
||||
|
||||
template <class ReversibleContainer>
|
||||
struct Mutable_ReversibleContainerConcept
|
||||
{
|
||||
typedef typename ReversibleContainer::iterator iterator;
|
||||
typedef typename ReversibleContainer::reverse_iterator reverse_iterator;
|
||||
|
||||
void constraints() {
|
||||
function_requires< ReversibleContainerConcept<ReversibleContainer> >();
|
||||
function_requires< Mutable_ForwardContainerConcept<ReversibleContainer> >();
|
||||
function_requires< Mutable_BidirectionalIteratorConcept<iterator> >();
|
||||
function_requires< Mutable_BidirectionalIteratorConcept<reverse_iterator> >();
|
||||
|
||||
reverse_iterator i = c.rbegin();
|
||||
i = c.rend();
|
||||
}
|
||||
ReversibleContainer c;
|
||||
};
|
||||
|
||||
template <class RandomAccessContainer>
|
||||
struct RandomAccessContainerConcept
|
||||
{
|
||||
typedef typename RandomAccessContainer::size_type size_type;
|
||||
typedef typename RandomAccessContainer::const_reference const_reference;
|
||||
typedef typename RandomAccessContainer::const_iterator const_iterator;
|
||||
typedef typename RandomAccessContainer::const_reverse_iterator
|
||||
const_reverse_iterator;
|
||||
|
||||
void constraints() {
|
||||
function_requires< ReversibleContainerConcept<RandomAccessContainer> >();
|
||||
function_requires< RandomAccessIteratorConcept<const_iterator> >();
|
||||
function_requires< RandomAccessIteratorConcept<const_reverse_iterator> >();
|
||||
|
||||
const RandomAccessContainer c;
|
||||
const_reference r = c[n];
|
||||
ignore_unused_variable_warning(r);
|
||||
}
|
||||
size_type n;
|
||||
};
|
||||
|
||||
template <class RandomAccessContainer>
|
||||
struct Mutable_RandomAccessContainerConcept
|
||||
{
|
||||
typedef typename RandomAccessContainer::size_type size_type;
|
||||
typedef typename RandomAccessContainer::reference reference;
|
||||
typedef typename RandomAccessContainer::iterator iterator;
|
||||
typedef typename RandomAccessContainer::reverse_iterator reverse_iterator;
|
||||
|
||||
void constraints() {
|
||||
function_requires< RandomAccessContainerConcept<RandomAccessContainer> >();
|
||||
function_requires< Mutable_ReversibleContainerConcept<RandomAccessContainer> >();
|
||||
function_requires< Mutable_RandomAccessIteratorConcept<iterator> >();
|
||||
function_requires< Mutable_RandomAccessIteratorConcept<reverse_iterator> >();
|
||||
|
||||
reference r = c[i];
|
||||
ignore_unused_variable_warning(r);
|
||||
}
|
||||
size_type i;
|
||||
RandomAccessContainer c;
|
||||
};
|
||||
|
||||
// A Sequence is inherently mutable
|
||||
template <class Sequence>
|
||||
struct SequenceConcept
|
||||
{
|
||||
|
||||
typedef typename Sequence::reference reference;
|
||||
typedef typename Sequence::const_reference const_reference;
|
||||
|
||||
void constraints() {
|
||||
// Matt Austern's book puts DefaultConstructible here, the C++
|
||||
// standard places it in Container
|
||||
// function_requires< DefaultConstructible<Sequence> >();
|
||||
function_requires< Mutable_ForwardContainerConcept<Sequence> >();
|
||||
function_requires< DefaultConstructibleConcept<Sequence> >();
|
||||
|
||||
Sequence
|
||||
c(n),
|
||||
c2(n, t),
|
||||
c3(first, last);
|
||||
|
||||
c.insert(p, t);
|
||||
c.insert(p, n, t);
|
||||
c.insert(p, first, last);
|
||||
|
||||
c.erase(p);
|
||||
c.erase(p, q);
|
||||
|
||||
reference r = c.front();
|
||||
|
||||
ignore_unused_variable_warning(c);
|
||||
ignore_unused_variable_warning(c2);
|
||||
ignore_unused_variable_warning(c3);
|
||||
ignore_unused_variable_warning(r);
|
||||
const_constraints(c);
|
||||
}
|
||||
void const_constraints(const Sequence& c) {
|
||||
const_reference r = c.front();
|
||||
ignore_unused_variable_warning(r);
|
||||
}
|
||||
typename Sequence::value_type t;
|
||||
typename Sequence::size_type n;
|
||||
typename Sequence::value_type* first, *last;
|
||||
typename Sequence::iterator p, q;
|
||||
};
|
||||
|
||||
template <class FrontInsertionSequence>
|
||||
struct FrontInsertionSequenceConcept
|
||||
{
|
||||
void constraints() {
|
||||
function_requires< SequenceConcept<FrontInsertionSequence> >();
|
||||
|
||||
c.push_front(t);
|
||||
c.pop_front();
|
||||
}
|
||||
FrontInsertionSequence c;
|
||||
typename FrontInsertionSequence::value_type t;
|
||||
};
|
||||
|
||||
template <class BackInsertionSequence>
|
||||
struct BackInsertionSequenceConcept
|
||||
{
|
||||
typedef typename BackInsertionSequence::reference reference;
|
||||
typedef typename BackInsertionSequence::const_reference const_reference;
|
||||
|
||||
void constraints() {
|
||||
function_requires< SequenceConcept<BackInsertionSequence> >();
|
||||
|
||||
c.push_back(t);
|
||||
c.pop_back();
|
||||
reference r = c.back();
|
||||
ignore_unused_variable_warning(r);
|
||||
}
|
||||
void const_constraints(const BackInsertionSequence& c) {
|
||||
const_reference r = c.back();
|
||||
ignore_unused_variable_warning(r);
|
||||
};
|
||||
BackInsertionSequence c;
|
||||
typename BackInsertionSequence::value_type t;
|
||||
};
|
||||
|
||||
template <class AssociativeContainer>
|
||||
struct AssociativeContainerConcept
|
||||
{
|
||||
void constraints() {
|
||||
function_requires< ForwardContainerConcept<AssociativeContainer> >();
|
||||
function_requires< DefaultConstructibleConcept<AssociativeContainer> >();
|
||||
|
||||
i = c.find(k);
|
||||
r = c.equal_range(k);
|
||||
c.erase(k);
|
||||
c.erase(i);
|
||||
c.erase(r.first, r.second);
|
||||
const_constraints(c);
|
||||
}
|
||||
void const_constraints(const AssociativeContainer& c) {
|
||||
ci = c.find(k);
|
||||
n = c.count(k);
|
||||
cr = c.equal_range(k);
|
||||
}
|
||||
typedef typename AssociativeContainer::iterator iterator;
|
||||
typedef typename AssociativeContainer::const_iterator const_iterator;
|
||||
|
||||
AssociativeContainer c;
|
||||
iterator i;
|
||||
std::pair<iterator,iterator> r;
|
||||
const_iterator ci;
|
||||
std::pair<const_iterator,const_iterator> cr;
|
||||
typename AssociativeContainer::key_type k;
|
||||
typename AssociativeContainer::size_type n;
|
||||
};
|
||||
|
||||
template <class UniqueAssociativeContainer>
|
||||
struct UniqueAssociativeContainerConcept
|
||||
{
|
||||
void constraints() {
|
||||
function_requires< AssociativeContainerConcept<UniqueAssociativeContainer> >();
|
||||
|
||||
UniqueAssociativeContainer c(first, last);
|
||||
|
||||
pos_flag = c.insert(t);
|
||||
c.insert(first, last);
|
||||
|
||||
ignore_unused_variable_warning(c);
|
||||
}
|
||||
std::pair<typename UniqueAssociativeContainer::iterator, bool> pos_flag;
|
||||
typename UniqueAssociativeContainer::value_type t;
|
||||
typename UniqueAssociativeContainer::value_type* first, *last;
|
||||
};
|
||||
|
||||
template <class MultipleAssociativeContainer>
|
||||
struct MultipleAssociativeContainerConcept
|
||||
{
|
||||
void constraints() {
|
||||
function_requires< AssociativeContainerConcept<MultipleAssociativeContainer> >();
|
||||
|
||||
MultipleAssociativeContainer c(first, last);
|
||||
|
||||
pos = c.insert(t);
|
||||
c.insert(first, last);
|
||||
|
||||
ignore_unused_variable_warning(c);
|
||||
ignore_unused_variable_warning(pos);
|
||||
}
|
||||
typename MultipleAssociativeContainer::iterator pos;
|
||||
typename MultipleAssociativeContainer::value_type t;
|
||||
typename MultipleAssociativeContainer::value_type* first, *last;
|
||||
};
|
||||
|
||||
template <class SimpleAssociativeContainer>
|
||||
struct SimpleAssociativeContainerConcept
|
||||
{
|
||||
void constraints() {
|
||||
function_requires< AssociativeContainerConcept<SimpleAssociativeContainer> >();
|
||||
typedef typename SimpleAssociativeContainer::key_type key_type;
|
||||
typedef typename SimpleAssociativeContainer::value_type value_type;
|
||||
typedef typename require_same<key_type, value_type>::type req;
|
||||
}
|
||||
};
|
||||
|
||||
template <class SimpleAssociativeContainer>
|
||||
struct PairAssociativeContainerConcept
|
||||
{
|
||||
void constraints() {
|
||||
function_requires< AssociativeContainerConcept<SimpleAssociativeContainer> >();
|
||||
typedef typename SimpleAssociativeContainer::key_type key_type;
|
||||
typedef typename SimpleAssociativeContainer::value_type value_type;
|
||||
typedef typename SimpleAssociativeContainer::mapped_type mapped_type;
|
||||
typedef std::pair<const key_type, mapped_type> required_value_type;
|
||||
typedef typename require_same<value_type, required_value_type>::type req;
|
||||
}
|
||||
};
|
||||
|
||||
template <class SortedAssociativeContainer>
|
||||
struct SortedAssociativeContainerConcept
|
||||
{
|
||||
void constraints() {
|
||||
function_requires< AssociativeContainerConcept<SortedAssociativeContainer> >();
|
||||
function_requires< ReversibleContainerConcept<SortedAssociativeContainer> >();
|
||||
|
||||
SortedAssociativeContainer
|
||||
c(kc),
|
||||
c2(first, last),
|
||||
c3(first, last, kc);
|
||||
|
||||
p = c.upper_bound(k);
|
||||
p = c.lower_bound(k);
|
||||
r = c.equal_range(k);
|
||||
|
||||
c.insert(p, t);
|
||||
|
||||
ignore_unused_variable_warning(c);
|
||||
ignore_unused_variable_warning(c2);
|
||||
ignore_unused_variable_warning(c3);
|
||||
}
|
||||
void const_constraints(const SortedAssociativeContainer& c) {
|
||||
kc = c.key_comp();
|
||||
vc = c.value_comp();
|
||||
|
||||
cp = c.upper_bound(k);
|
||||
cp = c.lower_bound(k);
|
||||
cr = c.equal_range(k);
|
||||
}
|
||||
typename SortedAssociativeContainer::key_compare kc;
|
||||
typename SortedAssociativeContainer::value_compare vc;
|
||||
typename SortedAssociativeContainer::value_type t;
|
||||
typename SortedAssociativeContainer::key_type k;
|
||||
typedef typename SortedAssociativeContainer::iterator iterator;
|
||||
typedef typename SortedAssociativeContainer::const_iterator const_iterator;
|
||||
iterator p;
|
||||
const_iterator cp;
|
||||
std::pair<iterator,iterator> r;
|
||||
std::pair<const_iterator,const_iterator> cr;
|
||||
typename SortedAssociativeContainer::value_type* first, *last;
|
||||
};
|
||||
|
||||
// HashedAssociativeContainer
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_CONCEPT_CHECKS_HPP
|
||||
|
Reference in New Issue
Block a user