Squashed 'third_party/boostorg/concept_check/' content from commit ed0a0eb
Change-Id: Ib7230965334f9501601efc300242efde8352a380
git-subtree-dir: third_party/boostorg/concept_check
git-subtree-split: ed0a0ebd72f778cfa4931e0538ea34c28db3a42b
diff --git a/include/boost/concept/assert.hpp b/include/boost/concept/assert.hpp
new file mode 100644
index 0000000..cf98179
--- /dev/null
+++ b/include/boost/concept/assert.hpp
@@ -0,0 +1,45 @@
+// Copyright David Abrahams 2006. 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)
+#ifndef BOOST_CONCEPT_ASSERT_DWA2006430_HPP
+# define BOOST_CONCEPT_ASSERT_DWA2006430_HPP
+
+# include <boost/config.hpp>
+# include <boost/detail/workaround.hpp>
+
+// The old protocol used a constraints() member function in concept
+// checking classes. If the compiler supports SFINAE, we can detect
+// that function and seamlessly support the old concept checking
+// classes. In this release, backward compatibility with the old
+// concept checking classes is enabled by default, where available.
+// The old protocol is deprecated, though, and backward compatibility
+// will no longer be the default in the next release.
+
+# if !defined(BOOST_NO_OLD_CONCEPT_SUPPORT) \
+ && !defined(BOOST_NO_SFINAE) \
+ \
+ && !(BOOST_WORKAROUND(__GNUC__, == 3) && BOOST_WORKAROUND(__GNUC_MINOR__, < 4))
+
+// Note: gcc-2.96 through 3.3.x have some SFINAE, but no ability to
+// check for the presence of particularmember functions.
+
+# define BOOST_OLD_CONCEPT_SUPPORT
+
+# endif
+
+# ifdef BOOST_MSVC
+# include <boost/concept/detail/msvc.hpp>
+# elif BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+# include <boost/concept/detail/borland.hpp>
+# else
+# include <boost/concept/detail/general.hpp>
+# endif
+
+ // Usage, in class or function context:
+ //
+ // BOOST_CONCEPT_ASSERT((UnaryFunctionConcept<F,bool,int>));
+ //
+# define BOOST_CONCEPT_ASSERT(ModelInParens) \
+ BOOST_CONCEPT_ASSERT_FN(void(*)ModelInParens)
+
+#endif // BOOST_CONCEPT_ASSERT_DWA2006430_HPP
diff --git a/include/boost/concept/detail/backward_compatibility.hpp b/include/boost/concept/detail/backward_compatibility.hpp
new file mode 100644
index 0000000..66d573e
--- /dev/null
+++ b/include/boost/concept/detail/backward_compatibility.hpp
@@ -0,0 +1,16 @@
+// Copyright David Abrahams 2009. 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)
+#ifndef BOOST_CONCEPT_BACKWARD_COMPATIBILITY_DWA200968_HPP
+# define BOOST_CONCEPT_BACKWARD_COMPATIBILITY_DWA200968_HPP
+
+namespace boost
+{
+ namespace concepts {}
+
+# if defined(BOOST_HAS_CONCEPTS) && !defined(BOOST_CONCEPT_NO_BACKWARD_KEYWORD)
+ namespace concept = concepts;
+# endif
+} // namespace boost::concept
+
+#endif // BOOST_CONCEPT_BACKWARD_COMPATIBILITY_DWA200968_HPP
diff --git a/include/boost/concept/detail/borland.hpp b/include/boost/concept/detail/borland.hpp
new file mode 100644
index 0000000..300d5d4
--- /dev/null
+++ b/include/boost/concept/detail/borland.hpp
@@ -0,0 +1,30 @@
+// Copyright David Abrahams 2006. 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)
+#ifndef BOOST_CONCEPT_DETAIL_BORLAND_DWA2006429_HPP
+# define BOOST_CONCEPT_DETAIL_BORLAND_DWA2006429_HPP
+
+# include <boost/preprocessor/cat.hpp>
+# include <boost/concept/detail/backward_compatibility.hpp>
+
+namespace boost { namespace concepts {
+
+template <class ModelFnPtr>
+struct require;
+
+template <class Model>
+struct require<void(*)(Model)>
+{
+ enum { instantiate = sizeof((((Model*)0)->~Model()), 3) };
+};
+
+# define BOOST_CONCEPT_ASSERT_FN( ModelFnPtr ) \
+ enum \
+ { \
+ BOOST_PP_CAT(boost_concept_check,__LINE__) = \
+ boost::concepts::require<ModelFnPtr>::instantiate \
+ }
+
+}} // namespace boost::concept
+
+#endif // BOOST_CONCEPT_DETAIL_BORLAND_DWA2006429_HPP
diff --git a/include/boost/concept/detail/concept_def.hpp b/include/boost/concept/detail/concept_def.hpp
new file mode 100644
index 0000000..750561e
--- /dev/null
+++ b/include/boost/concept/detail/concept_def.hpp
@@ -0,0 +1,34 @@
+// Copyright David Abrahams 2006. 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)
+#ifndef BOOST_CONCEPT_DETAIL_CONCEPT_DEF_DWA200651_HPP
+# define BOOST_CONCEPT_DETAIL_CONCEPT_DEF_DWA200651_HPP
+# include <boost/preprocessor/seq/for_each_i.hpp>
+# include <boost/preprocessor/seq/enum.hpp>
+# include <boost/preprocessor/comma_if.hpp>
+# include <boost/preprocessor/cat.hpp>
+#endif // BOOST_CONCEPT_DETAIL_CONCEPT_DEF_DWA200651_HPP
+
+// BOOST_concept(SomeName, (p1)(p2)...(pN))
+//
+// Expands to "template <class p1, class p2, ...class pN> struct SomeName"
+//
+// Also defines an equivalent SomeNameConcept for backward compatibility.
+// Maybe in the next release we can kill off the "Concept" suffix for good.
+# define BOOST_concept(name, params) \
+ template < BOOST_PP_SEQ_FOR_EACH_I(BOOST_CONCEPT_typename,~,params) > \
+ struct name; /* forward declaration */ \
+ \
+ template < BOOST_PP_SEQ_FOR_EACH_I(BOOST_CONCEPT_typename,~,params) > \
+ struct BOOST_PP_CAT(name,Concept) \
+ : name< BOOST_PP_SEQ_ENUM(params) > \
+ { \
+ }; \
+ \
+ template < BOOST_PP_SEQ_FOR_EACH_I(BOOST_CONCEPT_typename,~,params) > \
+ struct name
+
+// Helper for BOOST_concept, above.
+# define BOOST_CONCEPT_typename(r, ignored, index, t) \
+ BOOST_PP_COMMA_IF(index) typename t
+
diff --git a/include/boost/concept/detail/concept_undef.hpp b/include/boost/concept/detail/concept_undef.hpp
new file mode 100644
index 0000000..713db89
--- /dev/null
+++ b/include/boost/concept/detail/concept_undef.hpp
@@ -0,0 +1,5 @@
+// Copyright David Abrahams 2006. 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)
+# undef BOOST_concept_typename
+# undef BOOST_concept
diff --git a/include/boost/concept/detail/general.hpp b/include/boost/concept/detail/general.hpp
new file mode 100644
index 0000000..525ea65
--- /dev/null
+++ b/include/boost/concept/detail/general.hpp
@@ -0,0 +1,77 @@
+// Copyright David Abrahams 2006. 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)
+#ifndef BOOST_CONCEPT_DETAIL_GENERAL_DWA2006429_HPP
+# define BOOST_CONCEPT_DETAIL_GENERAL_DWA2006429_HPP
+
+# include <boost/config.hpp>
+# include <boost/preprocessor/cat.hpp>
+# include <boost/concept/detail/backward_compatibility.hpp>
+
+# ifdef BOOST_OLD_CONCEPT_SUPPORT
+# include <boost/concept/detail/has_constraints.hpp>
+# include <boost/mpl/if.hpp>
+# endif
+
+// This implementation works on Comeau and GCC, all the way back to
+// 2.95
+namespace boost { namespace concepts {
+
+template <class ModelFn>
+struct requirement_;
+
+namespace detail
+{
+ template <void(*)()> struct instantiate {};
+}
+
+template <class Model>
+struct requirement
+{
+ static void failed() { ((Model*)0)->~Model(); }
+};
+
+struct failed {};
+
+template <class Model>
+struct requirement<failed ************ Model::************>
+{
+ static void failed() { ((Model*)0)->~Model(); }
+};
+
+# ifdef BOOST_OLD_CONCEPT_SUPPORT
+
+template <class Model>
+struct constraint
+{
+ static void failed() { ((Model*)0)->constraints(); }
+};
+
+template <class Model>
+struct requirement_<void(*)(Model)>
+ : mpl::if_<
+ concepts::not_satisfied<Model>
+ , constraint<Model>
+ , requirement<failed ************ Model::************>
+ >::type
+{};
+
+# else
+
+// For GCC-2.x, these can't have exactly the same name
+template <class Model>
+struct requirement_<void(*)(Model)>
+ : requirement<failed ************ Model::************>
+{};
+
+# endif
+
+# define BOOST_CONCEPT_ASSERT_FN( ModelFnPtr ) \
+ typedef ::boost::concepts::detail::instantiate< \
+ &::boost::concepts::requirement_<ModelFnPtr>::failed> \
+ BOOST_PP_CAT(boost_concept_check,__LINE__) \
+ BOOST_ATTRIBUTE_UNUSED
+
+}}
+
+#endif // BOOST_CONCEPT_DETAIL_GENERAL_DWA2006429_HPP
diff --git a/include/boost/concept/detail/has_constraints.hpp b/include/boost/concept/detail/has_constraints.hpp
new file mode 100644
index 0000000..a309db3
--- /dev/null
+++ b/include/boost/concept/detail/has_constraints.hpp
@@ -0,0 +1,50 @@
+// Copyright David Abrahams 2006. 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)
+#ifndef BOOST_CONCEPT_DETAIL_HAS_CONSTRAINTS_DWA2006429_HPP
+# define BOOST_CONCEPT_DETAIL_HAS_CONSTRAINTS_DWA2006429_HPP
+
+# include <boost/mpl/bool.hpp>
+# include <boost/detail/workaround.hpp>
+# include <boost/concept/detail/backward_compatibility.hpp>
+
+namespace boost { namespace concepts {
+
+namespace detail
+{
+
+// Here we implement the metafunction that detects whether a
+// constraints metafunction exists
+ typedef char yes;
+ typedef char (&no)[2];
+
+ template <class Model, void (Model::*)()>
+ struct wrap_constraints {};
+
+#if BOOST_WORKAROUND(__SUNPRO_CC, <= 0x580) || defined(__CUDACC__)
+ // Work around the following bogus error in Sun Studio 11, by
+ // turning off the has_constraints function entirely:
+ // Error: complex expression not allowed in dependent template
+ // argument expression
+ inline no has_constraints_(...);
+#else
+ template <class Model>
+ inline yes has_constraints_(Model*, wrap_constraints<Model,&Model::constraints>* = 0);
+ inline no has_constraints_(...);
+#endif
+}
+
+// This would be called "detail::has_constraints," but it has a strong
+// tendency to show up in error messages.
+template <class Model>
+struct not_satisfied
+{
+ BOOST_STATIC_CONSTANT(
+ bool
+ , value = sizeof( detail::has_constraints_((Model*)0) ) == sizeof(detail::yes) );
+ typedef mpl::bool_<value> type;
+};
+
+}} // namespace boost::concepts::detail
+
+#endif // BOOST_CONCEPT_DETAIL_HAS_CONSTRAINTS_DWA2006429_HPP
diff --git a/include/boost/concept/detail/msvc.hpp b/include/boost/concept/detail/msvc.hpp
new file mode 100644
index 0000000..078dd22
--- /dev/null
+++ b/include/boost/concept/detail/msvc.hpp
@@ -0,0 +1,123 @@
+// Copyright David Abrahams 2006. 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)
+#ifndef BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP
+# define BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP
+
+# include <boost/preprocessor/cat.hpp>
+# include <boost/concept/detail/backward_compatibility.hpp>
+# include <boost/config.hpp>
+
+# ifdef BOOST_OLD_CONCEPT_SUPPORT
+# include <boost/concept/detail/has_constraints.hpp>
+# include <boost/mpl/if.hpp>
+# endif
+
+# ifdef BOOST_MSVC
+# pragma warning(push)
+# pragma warning(disable:4100)
+# endif
+
+namespace boost { namespace concepts {
+
+
+template <class Model>
+struct check
+{
+ virtual void failed(Model* x)
+ {
+ x->~Model();
+ }
+};
+
+# ifndef BOOST_NO_PARTIAL_SPECIALIZATION
+struct failed {};
+template <class Model>
+struct check<failed ************ Model::************>
+{
+ virtual void failed(Model* x)
+ {
+ x->~Model();
+ }
+};
+# endif
+
+# ifdef BOOST_OLD_CONCEPT_SUPPORT
+
+namespace detail
+{
+ // No need for a virtual function here, since evaluating
+ // not_satisfied below will have already instantiated the
+ // constraints() member.
+ struct constraint {};
+}
+
+template <class Model>
+struct require
+ : mpl::if_c<
+ not_satisfied<Model>::value
+ , detail::constraint
+# ifndef BOOST_NO_PARTIAL_SPECIALIZATION
+ , check<Model>
+# else
+ , check<failed ************ Model::************>
+# endif
+ >::type
+{};
+
+# else
+
+template <class Model>
+struct require
+# ifndef BOOST_NO_PARTIAL_SPECIALIZATION
+ : check<Model>
+# else
+ : check<failed ************ Model::************>
+# endif
+{};
+
+# endif
+
+# if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
+
+//
+// The iterator library sees some really strange errors unless we
+// do things this way.
+//
+template <class Model>
+struct require<void(*)(Model)>
+{
+ virtual void failed(Model*)
+ {
+ require<Model>();
+ }
+};
+
+# define BOOST_CONCEPT_ASSERT_FN( ModelFnPtr ) \
+enum \
+{ \
+ BOOST_PP_CAT(boost_concept_check,__LINE__) = \
+ sizeof(::boost::concepts::require<ModelFnPtr>) \
+}
+
+# else // Not vc-7.1
+
+template <class Model>
+require<Model>
+require_(void(*)(Model));
+
+# define BOOST_CONCEPT_ASSERT_FN( ModelFnPtr ) \
+enum \
+{ \
+ BOOST_PP_CAT(boost_concept_check,__LINE__) = \
+ sizeof(::boost::concepts::require_((ModelFnPtr)0)) \
+}
+
+# endif
+}}
+
+# ifdef BOOST_MSVC
+# pragma warning(pop)
+# endif
+
+#endif // BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP
diff --git a/include/boost/concept/requires.hpp b/include/boost/concept/requires.hpp
new file mode 100644
index 0000000..365ce10
--- /dev/null
+++ b/include/boost/concept/requires.hpp
@@ -0,0 +1,93 @@
+// Copyright David Abrahams 2006. 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)
+#ifndef BOOST_CONCEPT_REQUIRES_DWA2006430_HPP
+# define BOOST_CONCEPT_REQUIRES_DWA2006430_HPP
+
+# include <boost/config.hpp>
+# include <boost/concept/assert.hpp>
+# include <boost/preprocessor/seq/for_each.hpp>
+
+namespace boost {
+
+// unaryfunptr_arg_type from parameter/aux_/parenthesized_type.hpp
+
+namespace ccheck_aux {
+
+// A metafunction that transforms void(*)(T) -> T
+template <class UnaryFunctionPointer>
+struct unaryfunptr_arg_type;
+
+template <class Arg>
+struct unaryfunptr_arg_type<void(*)(Arg)>
+{
+ typedef Arg type;
+};
+
+template <>
+struct unaryfunptr_arg_type<void(*)(void)>
+{
+ typedef void type;
+};
+
+} // namespace ccheck_aux
+
+// Template for use in handwritten assertions
+template <class Model, class More>
+struct requires_ : More
+{
+ BOOST_CONCEPT_ASSERT((Model));
+};
+
+// Template for use by macros, where models must be wrapped in parens.
+// This isn't in namespace detail to keep extra cruft out of resulting
+// error messages.
+template <class ModelFn>
+struct _requires_
+{
+ enum { value = 0 };
+ BOOST_CONCEPT_ASSERT_FN(ModelFn);
+};
+
+template <int check, class Result>
+struct Requires_ : ::boost::ccheck_aux::unaryfunptr_arg_type<Result>
+{
+};
+
+# if BOOST_WORKAROUND(BOOST_INTEL_WIN, BOOST_TESTED_AT(1010))
+# define BOOST_CONCEPT_REQUIRES_(r,data,t) | (::boost::_requires_<void(*)t>::value)
+# else
+# define BOOST_CONCEPT_REQUIRES_(r,data,t) + (::boost::_requires_<void(*)t>::value)
+# endif
+
+#if defined(NDEBUG)
+
+# define BOOST_CONCEPT_REQUIRES(models, result) \
+ typename ::boost::ccheck_aux::unaryfunptr_arg_type<void(*)result>::type
+
+#elif BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+
+// Same thing as below without the initial typename
+# define BOOST_CONCEPT_REQUIRES(models, result) \
+ ::boost::Requires_< \
+ (0 BOOST_PP_SEQ_FOR_EACH(BOOST_CONCEPT_REQUIRES_, ~, models)), \
+ ::boost::ccheck_aux::unaryfunptr_arg_type<void(*)result> \
+ >::type
+
+#else
+
+// This just ICEs on MSVC6 :(
+# define BOOST_CONCEPT_REQUIRES(models, result) \
+ typename ::boost::Requires_< \
+ (0 BOOST_PP_SEQ_FOR_EACH(BOOST_CONCEPT_REQUIRES_, ~, models)), \
+ void(*)result \
+ >::type
+
+#endif
+
+// C++0x proposed syntax changed. This supports an older usage
+#define BOOST_CONCEPT_WHERE(models,result) BOOST_CONCEPT_REQUIRES(models,result)
+
+} // namespace boost::concept_check
+
+#endif // BOOST_CONCEPT_REQUIRES_DWA2006430_HPP
diff --git a/include/boost/concept/usage.hpp b/include/boost/concept/usage.hpp
new file mode 100644
index 0000000..e73370f
--- /dev/null
+++ b/include/boost/concept/usage.hpp
@@ -0,0 +1,36 @@
+// Copyright David Abrahams 2006. 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)
+#ifndef BOOST_CONCEPT_USAGE_DWA2006919_HPP
+# define BOOST_CONCEPT_USAGE_DWA2006919_HPP
+
+# include <boost/concept/assert.hpp>
+# include <boost/detail/workaround.hpp>
+# include <boost/concept/detail/backward_compatibility.hpp>
+
+namespace boost { namespace concepts {
+
+template <class Model>
+struct usage_requirements
+{
+ ~usage_requirements() { ((Model*)0)->~Model(); }
+};
+
+# if BOOST_WORKAROUND(__GNUC__, <= 3)
+
+# define BOOST_CONCEPT_USAGE(model) \
+ model(); /* at least 2.96 and 3.4.3 both need this :( */ \
+ BOOST_CONCEPT_ASSERT((boost::concepts::usage_requirements<model>)); \
+ ~model()
+
+# else
+
+# define BOOST_CONCEPT_USAGE(model) \
+ BOOST_CONCEPT_ASSERT((boost::concepts::usage_requirements<model>)); \
+ ~model()
+
+# endif
+
+}} // namespace boost::concepts
+
+#endif // BOOST_CONCEPT_USAGE_DWA2006919_HPP
diff --git a/include/boost/concept_archetype.hpp b/include/boost/concept_archetype.hpp
new file mode 100644
index 0000000..f2455fd
--- /dev/null
+++ b/include/boost/concept_archetype.hpp
@@ -0,0 +1,670 @@
+//
+// (C) Copyright Jeremy Siek 2000.
+// 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)
+//
+// Revision History:
+//
+// 17 July 2001: Added const to some member functions. (Jeremy Siek)
+// 05 May 2001: Removed static dummy_cons object. (Jeremy Siek)
+
+// See http://www.boost.org/libs/concept_check for documentation.
+
+#ifndef BOOST_CONCEPT_ARCHETYPES_HPP
+#define BOOST_CONCEPT_ARCHETYPES_HPP
+
+#include <boost/config.hpp>
+#include <boost/mpl/identity.hpp>
+#include <functional>
+#include <iterator> // iterator tags
+#include <cstddef> // std::ptrdiff_t
+
+namespace boost {
+
+ //===========================================================================
+ // Basic Archetype Classes
+
+ namespace detail {
+ class dummy_constructor { };
+ }
+
+ // 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) { }
+#ifndef __MWERKS__
+ template <class TT>
+ friend void dummy_friend(); // just to avoid warnings
+#endif
+ };
+
+ // This is a helper class that provides a way to get a reference to
+ // an object. The get() function will never be called at run-time
+ // (nothing in this file will) so this seemingly very bad function
+ // is really quite innocent. The name of this class needs to be
+ // changed.
+ template <class T>
+ class static_object
+ {
+ public:
+ static T& get()
+ {
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+ return *reinterpret_cast<T*>(0);
+#else
+ static char d[sizeof(T)];
+ return *reinterpret_cast<T*>(d);
+#endif
+ }
+ };
+
+ template <class Base = null_archetype<> >
+ class default_constructible_archetype : public Base {
+ public:
+ default_constructible_archetype()
+ : Base(static_object<detail::dummy_constructor>::get()) { }
+ 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(static_object<detail::dummy_constructor>::get()) { }
+ copy_constructible_archetype(const copy_constructible_archetype&)
+ : Base(static_object<detail::dummy_constructor>::get()) { }
+ 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(static_object<detail::dummy_constructor>::get()) { }
+ 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) { }
+ };
+
+ // 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) { }
+ 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(static_object<detail::dummy_constructor>::get());
+ }
+ template <class Base>
+ boolean_archetype
+ operator!=(const equality_comparable_archetype<Base>&,
+ const equality_comparable_archetype<Base>&)
+ {
+ return boolean_archetype(static_object<detail::dummy_constructor>::get());
+ }
+
+
+ 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(static_object<detail::dummy_constructor>::get());
+ }
+ template <class Base1, class Base2>
+ boolean_archetype
+ operator!=(const equality_comparable2_first_archetype<Base1>&,
+ const equality_comparable2_second_archetype<Base2>&)
+ {
+ return boolean_archetype(static_object<detail::dummy_constructor>::get());
+ }
+
+
+ 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(static_object<detail::dummy_constructor>::get());
+ }
+
+
+
+ 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(static_object<detail::dummy_constructor>::get());
+ }
+ template <class Base>
+ boolean_archetype
+ operator<=(const comparable_archetype<Base>&,
+ const comparable_archetype<Base>&)
+ {
+ return boolean_archetype(static_object<detail::dummy_constructor>::get());
+ }
+ template <class Base>
+ boolean_archetype
+ operator>(const comparable_archetype<Base>&,
+ const comparable_archetype<Base>&)
+ {
+ return boolean_archetype(static_object<detail::dummy_constructor>::get());
+ }
+ template <class Base>
+ boolean_archetype
+ operator>=(const comparable_archetype<Base>&,
+ const comparable_archetype<Base>&)
+ {
+ return boolean_archetype(static_object<detail::dummy_constructor>::get());
+ }
+
+
+ // 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(static_object<detail::dummy_constructor>::get()); \
+ }
+
+ 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(static_object<detail::dummy_constructor>::get()) { } \
+ 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>(static_object<detail::dummy_constructor>::get()); \
+ }
+
+ 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(static_object<detail::dummy_constructor>::get()); \
+ }
+
+ 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&) const {
+ 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&) const {
+ 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&) const {
+ 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&) const {
+ return static_object<Return>::get();
+ }
+ };
+
+ //===========================================================================
+ // Iterator Archetype Classes
+
+ template <class T, int I = 0>
+ class input_iterator_archetype
+ {
+ private:
+ typedef input_iterator_archetype self;
+ public:
+ typedef std::input_iterator_tag iterator_category;
+ typedef T value_type;
+ struct reference {
+ operator const value_type&() const { return static_object<T>::get(); }
+ };
+ typedef const T* pointer;
+ typedef std::ptrdiff_t difference_type;
+ self& operator=(const self&) { return *this; }
+ bool operator==(const self&) const { return true; }
+ bool operator!=(const self&) const { return true; }
+ reference operator*() const { return reference(); }
+ self& operator++() { return *this; }
+ self operator++(int) { return *this; }
+ };
+
+ template <class T>
+ class input_iterator_archetype_no_proxy
+ {
+ private:
+ typedef input_iterator_archetype_no_proxy 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;
+ 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(detail::dummy_constructor) { }
+ output_iterator_archetype(const self&) { }
+ 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; }
+ private:
+ output_iterator_archetype() { }
+ };
+
+ template <class T>
+ class input_output_iterator_archetype
+ {
+ private:
+ typedef input_output_iterator_archetype self;
+ struct in_out_tag : public std::input_iterator_tag, public std::output_iterator_tag { };
+ public:
+ typedef in_out_tag iterator_category;
+ typedef T value_type;
+ struct reference {
+ reference& operator=(const T&) { return *this; }
+ operator value_type() { return static_object<T>::get(); }
+ };
+ typedef const T* pointer;
+ typedef std::ptrdiff_t difference_type;
+ input_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 reference(); }
+ 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 const T& reference;
+ typedef T const* 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 mutable_forward_iterator_archetype
+ {
+ public:
+ typedef mutable_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;
+ mutable_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 const 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 mutable_bidirectional_iterator_archetype
+ {
+ public:
+ typedef mutable_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;
+ mutable_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 const 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) const
+ { 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) const { return *this; }
+ self operator-(difference_type) const { return *this; }
+ bool operator<(const self&) const { return true; }
+ bool operator<=(const self&) const { return true; }
+ bool operator>(const self&) const { return true; }
+ bool operator>=(const self&) const { 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; }
+
+
+ template <class T>
+ class mutable_random_access_iterator_archetype
+ {
+ public:
+ typedef mutable_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;
+ mutable_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) const
+ { 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) const { return *this; }
+ self operator-(difference_type) const { return *this; }
+ bool operator<(const self&) const { return true; }
+ bool operator<=(const self&) const { return true; }
+ bool operator>(const self&) const { return true; }
+ bool operator>=(const self&) const { return true; }
+ };
+ template <class T>
+ mutable_random_access_iterator_archetype<T>
+ operator+
+ (typename mutable_random_access_iterator_archetype<T>::difference_type,
+ const mutable_random_access_iterator_archetype<T>& x)
+ { return x; }
+
+} // namespace boost
+
+#endif // BOOST_CONCEPT_ARCHETYPES_H
diff --git a/include/boost/concept_check.hpp b/include/boost/concept_check.hpp
new file mode 100644
index 0000000..25f118b
--- /dev/null
+++ b/include/boost/concept_check.hpp
@@ -0,0 +1,1082 @@
+//
+// (C) Copyright Jeremy Siek 2000.
+// Copyright 2002 The Trustees of Indiana University.
+//
+// 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)
+//
+// Revision History:
+// 05 May 2001: Workarounds for HP aCC from Thomas Matelich. (Jeremy Siek)
+// 02 April 2001: Removed limits header altogether. (Jeremy Siek)
+// 01 April 2001: Modified to use new <boost/limits.hpp> header. (JMaddock)
+//
+
+// See http://www.boost.org/libs/concept_check for documentation.
+
+#ifndef BOOST_CONCEPT_CHECKS_HPP
+# define BOOST_CONCEPT_CHECKS_HPP
+
+# include <boost/concept/assert.hpp>
+
+# include <iterator>
+# include <boost/type_traits/conversion_traits.hpp>
+# include <utility>
+# include <boost/type_traits/is_same.hpp>
+# include <boost/type_traits/is_void.hpp>
+# include <boost/mpl/assert.hpp>
+# include <boost/mpl/bool.hpp>
+# include <boost/detail/workaround.hpp>
+
+# include <boost/concept/usage.hpp>
+# include <boost/concept/detail/concept_def.hpp>
+
+#if (defined _MSC_VER)
+# pragma warning( push )
+# pragma warning( disable : 4510 ) // default constructor could not be generated
+# pragma warning( disable : 4610 ) // object 'class' can never be instantiated - user-defined constructor required
+#endif
+
+namespace boost
+{
+
+ //
+ // Backward compatibility
+ //
+
+ template <class Model>
+ inline void function_requires(Model* = 0)
+ {
+ BOOST_CONCEPT_ASSERT((Model));
+ }
+ template <class T> inline void ignore_unused_variable_warning(T const&) {}
+
+# define BOOST_CLASS_REQUIRE(type_var, ns, concept) \
+ BOOST_CONCEPT_ASSERT((ns::concept<type_var>))
+
+# define BOOST_CLASS_REQUIRE2(type_var1, type_var2, ns, concept) \
+ BOOST_CONCEPT_ASSERT((ns::concept<type_var1,type_var2>))
+
+# define BOOST_CLASS_REQUIRE3(tv1, tv2, tv3, ns, concept) \
+ BOOST_CONCEPT_ASSERT((ns::concept<tv1,tv2,tv3>))
+
+# define BOOST_CLASS_REQUIRE4(tv1, tv2, tv3, tv4, ns, concept) \
+ BOOST_CONCEPT_ASSERT((ns::concept<tv1,tv2,tv3,tv4>))
+
+
+ //
+ // Begin concept definitions
+ //
+ BOOST_concept(Integer, (T))
+ {
+ BOOST_CONCEPT_USAGE(Integer)
+ {
+ x.error_type_must_be_an_integer_type();
+ }
+ private:
+ T x;
+ };
+
+ template <> struct Integer<char> {};
+ template <> struct Integer<signed char> {};
+ template <> struct Integer<unsigned char> {};
+ template <> struct Integer<short> {};
+ template <> struct Integer<unsigned short> {};
+ template <> struct Integer<int> {};
+ template <> struct Integer<unsigned int> {};
+ template <> struct Integer<long> {};
+ template <> struct Integer<unsigned long> {};
+# if defined(BOOST_HAS_LONG_LONG)
+ template <> struct Integer< ::boost::long_long_type> {};
+ template <> struct Integer< ::boost::ulong_long_type> {};
+# elif defined(BOOST_HAS_MS_INT64)
+ template <> struct Integer<__int64> {};
+ template <> struct Integer<unsigned __int64> {};
+# endif
+
+ BOOST_concept(SignedInteger,(T)) {
+ BOOST_CONCEPT_USAGE(SignedInteger) {
+ x.error_type_must_be_a_signed_integer_type();
+ }
+ private:
+ T x;
+ };
+ template <> struct SignedInteger<signed char> { };
+ template <> struct SignedInteger<short> {};
+ template <> struct SignedInteger<int> {};
+ template <> struct SignedInteger<long> {};
+# if defined(BOOST_HAS_LONG_LONG)
+ template <> struct SignedInteger< ::boost::long_long_type> {};
+# elif defined(BOOST_HAS_MS_INT64)
+ template <> struct SignedInteger<__int64> {};
+# endif
+
+ BOOST_concept(UnsignedInteger,(T)) {
+ BOOST_CONCEPT_USAGE(UnsignedInteger) {
+ x.error_type_must_be_an_unsigned_integer_type();
+ }
+ private:
+ T x;
+ };
+
+ template <> struct UnsignedInteger<unsigned char> {};
+ template <> struct UnsignedInteger<unsigned short> {};
+ template <> struct UnsignedInteger<unsigned int> {};
+ template <> struct UnsignedInteger<unsigned long> {};
+# if defined(BOOST_HAS_LONG_LONG)
+ template <> struct UnsignedInteger< ::boost::ulong_long_type> {};
+# elif defined(BOOST_HAS_MS_INT64)
+ template <> struct UnsignedInteger<unsigned __int64> {};
+# endif
+
+ //===========================================================================
+ // Basic Concepts
+
+ BOOST_concept(DefaultConstructible,(TT))
+ {
+ BOOST_CONCEPT_USAGE(DefaultConstructible) {
+ TT a; // require default constructor
+ ignore_unused_variable_warning(a);
+ }
+ };
+
+ BOOST_concept(Assignable,(TT))
+ {
+ BOOST_CONCEPT_USAGE(Assignable) {
+#if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
+ a = b; // require assignment operator
+#endif
+ const_constraints(b);
+ }
+ private:
+ void const_constraints(const TT& x) {
+#if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
+ a = x; // const required for argument to assignment
+#else
+ ignore_unused_variable_warning(x);
+#endif
+ }
+ private:
+ TT a;
+ TT b;
+ };
+
+
+ BOOST_concept(CopyConstructible,(TT))
+ {
+ BOOST_CONCEPT_USAGE(CopyConstructible) {
+ TT a(b); // require copy constructor
+ TT* ptr = &a; // require address of operator
+ const_constraints(a);
+ ignore_unused_variable_warning(ptr);
+ }
+ private:
+ 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=
+ BOOST_concept(SGIAssignable,(TT))
+ {
+ BOOST_CONCEPT_USAGE(SGIAssignable) {
+ TT c(a);
+#if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
+ a = b; // require assignment operator
+#endif
+ const_constraints(b);
+ ignore_unused_variable_warning(c);
+ }
+ private:
+ void const_constraints(const TT& x) {
+ TT c(x);
+#if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
+ a = x; // const required for argument to assignment
+#endif
+ ignore_unused_variable_warning(c);
+ }
+ TT a;
+ TT b;
+ };
+
+ BOOST_concept(Convertible,(X)(Y))
+ {
+ BOOST_CONCEPT_USAGE(Convertible) {
+ Y y = x;
+ ignore_unused_variable_warning(y);
+ }
+ private:
+ 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);
+ }
+
+ BOOST_concept(EqualityComparable,(TT))
+ {
+ BOOST_CONCEPT_USAGE(EqualityComparable) {
+ require_boolean_expr(a == b);
+ require_boolean_expr(a != b);
+ }
+ private:
+ TT a, b;
+ };
+
+ BOOST_concept(LessThanComparable,(TT))
+ {
+ BOOST_CONCEPT_USAGE(LessThanComparable) {
+ require_boolean_expr(a < b);
+ }
+ private:
+ TT a, b;
+ };
+
+ // This is equivalent to SGI STL's LessThanComparable.
+ BOOST_concept(Comparable,(TT))
+ {
+ BOOST_CONCEPT_USAGE(Comparable) {
+ require_boolean_expr(a < b);
+ require_boolean_expr(a > b);
+ require_boolean_expr(a <= b);
+ require_boolean_expr(a >= b);
+ }
+ private:
+ TT a, b;
+ };
+
+#define BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(OP,NAME) \
+ BOOST_concept(NAME, (First)(Second)) \
+ { \
+ BOOST_CONCEPT_USAGE(NAME) { (void)constraints_(); } \
+ private: \
+ bool constraints_() { return a OP b; } \
+ First a; \
+ Second b; \
+ }
+
+#define BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(OP,NAME) \
+ BOOST_concept(NAME, (Ret)(First)(Second)) \
+ { \
+ BOOST_CONCEPT_USAGE(NAME) { (void)constraints_(); } \
+ private: \
+ Ret constraints_() { return a OP b; } \
+ First a; \
+ Second b; \
+ }
+
+ BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(==, EqualOp);
+ BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(!=, NotEqualOp);
+ BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<, LessThanOp);
+ BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<=, LessEqualOp);
+ BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>, GreaterThanOp);
+ BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>=, GreaterEqualOp);
+
+ BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(+, PlusOp);
+ BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(*, TimesOp);
+ BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(/, DivideOp);
+ BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(-, SubtractOp);
+ BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(%, ModOp);
+
+ //===========================================================================
+ // Function Object Concepts
+
+ BOOST_concept(Generator,(Func)(Return))
+ {
+ BOOST_CONCEPT_USAGE(Generator) { test(is_void<Return>()); }
+
+ private:
+ void test(boost::mpl::false_)
+ {
+ // Do we really want a reference here?
+ const Return& r = f();
+ ignore_unused_variable_warning(r);
+ }
+
+ void test(boost::mpl::true_)
+ {
+ f();
+ }
+
+ Func f;
+ };
+
+ BOOST_concept(UnaryFunction,(Func)(Return)(Arg))
+ {
+ BOOST_CONCEPT_USAGE(UnaryFunction) { test(is_void<Return>()); }
+
+ private:
+ void test(boost::mpl::false_)
+ {
+ f(arg); // "priming the pump" this way keeps msvc6 happy (ICE)
+ Return r = f(arg);
+ ignore_unused_variable_warning(r);
+ }
+
+ void test(boost::mpl::true_)
+ {
+ f(arg);
+ }
+
+#if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \
+ && BOOST_WORKAROUND(__GNUC__, > 3)))
+ // Declare a dummy construktor to make gcc happy.
+ // It seems the compiler can not generate a sensible constructor when this is instantiated with a refence type.
+ // (warning: non-static reference "const double& boost::UnaryFunction<YourClassHere>::arg"
+ // in class without a constructor [-Wuninitialized])
+ UnaryFunction();
+#endif
+
+ Func f;
+ Arg arg;
+ };
+
+ BOOST_concept(BinaryFunction,(Func)(Return)(First)(Second))
+ {
+ BOOST_CONCEPT_USAGE(BinaryFunction) { test(is_void<Return>()); }
+ private:
+ void test(boost::mpl::false_)
+ {
+ f(first,second);
+ Return r = f(first, second); // require operator()
+ (void)r;
+ }
+
+ void test(boost::mpl::true_)
+ {
+ f(first,second);
+ }
+
+#if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \
+ && BOOST_WORKAROUND(__GNUC__, > 3)))
+ // Declare a dummy constructor to make gcc happy.
+ // It seems the compiler can not generate a sensible constructor when this is instantiated with a refence type.
+ // (warning: non-static reference "const double& boost::BinaryFunction<YourClassHere>::arg"
+ // in class without a constructor [-Wuninitialized])
+ BinaryFunction();
+#endif
+
+ Func f;
+ First first;
+ Second second;
+ };
+
+ BOOST_concept(UnaryPredicate,(Func)(Arg))
+ {
+ BOOST_CONCEPT_USAGE(UnaryPredicate) {
+ require_boolean_expr(f(arg)); // require operator() returning bool
+ }
+ private:
+#if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \
+ && BOOST_WORKAROUND(__GNUC__, > 3)))
+ // Declare a dummy constructor to make gcc happy.
+ // It seems the compiler can not generate a sensible constructor when this is instantiated with a refence type.
+ // (warning: non-static reference "const double& boost::UnaryPredicate<YourClassHere>::arg"
+ // in class without a constructor [-Wuninitialized])
+ UnaryPredicate();
+#endif
+
+ Func f;
+ Arg arg;
+ };
+
+ BOOST_concept(BinaryPredicate,(Func)(First)(Second))
+ {
+ BOOST_CONCEPT_USAGE(BinaryPredicate) {
+ require_boolean_expr(f(a, b)); // require operator() returning bool
+ }
+ private:
+#if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \
+ && BOOST_WORKAROUND(__GNUC__, > 3)))
+ // Declare a dummy constructor to make gcc happy.
+ // It seems the compiler can not generate a sensible constructor when this is instantiated with a refence type.
+ // (warning: non-static reference "const double& boost::BinaryPredicate<YourClassHere>::arg"
+ // in class without a constructor [-Wuninitialized])
+ BinaryPredicate();
+#endif
+ Func f;
+ First a;
+ Second b;
+ };
+
+ // use this when functor is used inside a container class like std::set
+ BOOST_concept(Const_BinaryPredicate,(Func)(First)(Second))
+ : BinaryPredicate<Func, First, Second>
+ {
+ BOOST_CONCEPT_USAGE(Const_BinaryPredicate) {
+ const_constraints(f);
+ }
+ private:
+ void const_constraints(const Func& fun) {
+ // operator() must be a const member function
+ require_boolean_expr(fun(a, b));
+ }
+#if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \
+ && BOOST_WORKAROUND(__GNUC__, > 3)))
+ // Declare a dummy constructor to make gcc happy.
+ // It seems the compiler can not generate a sensible constructor when this is instantiated with a refence type.
+ // (warning: non-static reference "const double& boost::Const_BinaryPredicate<YourClassHere>::arg"
+ // in class without a constructor [-Wuninitialized])
+ Const_BinaryPredicate();
+#endif
+
+ Func f;
+ First a;
+ Second b;
+ };
+
+ BOOST_concept(AdaptableGenerator,(Func)(Return))
+ : Generator<Func, typename Func::result_type>
+ {
+ typedef typename Func::result_type result_type;
+
+ BOOST_CONCEPT_USAGE(AdaptableGenerator)
+ {
+ BOOST_CONCEPT_ASSERT((Convertible<result_type, Return>));
+ }
+ };
+
+ BOOST_concept(AdaptableUnaryFunction,(Func)(Return)(Arg))
+ : UnaryFunction<Func, typename Func::result_type, typename Func::argument_type>
+ {
+ typedef typename Func::argument_type argument_type;
+ typedef typename Func::result_type result_type;
+
+ ~AdaptableUnaryFunction()
+ {
+ BOOST_CONCEPT_ASSERT((Convertible<result_type, Return>));
+ BOOST_CONCEPT_ASSERT((Convertible<Arg, argument_type>));
+ }
+ };
+
+ BOOST_concept(AdaptableBinaryFunction,(Func)(Return)(First)(Second))
+ : BinaryFunction<
+ Func
+ , typename Func::result_type
+ , typename Func::first_argument_type
+ , typename Func::second_argument_type
+ >
+ {
+ typedef typename Func::first_argument_type first_argument_type;
+ typedef typename Func::second_argument_type second_argument_type;
+ typedef typename Func::result_type result_type;
+
+ ~AdaptableBinaryFunction()
+ {
+ BOOST_CONCEPT_ASSERT((Convertible<result_type, Return>));
+ BOOST_CONCEPT_ASSERT((Convertible<First, first_argument_type>));
+ BOOST_CONCEPT_ASSERT((Convertible<Second, second_argument_type>));
+ }
+ };
+
+ BOOST_concept(AdaptablePredicate,(Func)(Arg))
+ : UnaryPredicate<Func, Arg>
+ , AdaptableUnaryFunction<Func, bool, Arg>
+ {
+ };
+
+ BOOST_concept(AdaptableBinaryPredicate,(Func)(First)(Second))
+ : BinaryPredicate<Func, First, Second>
+ , AdaptableBinaryFunction<Func, bool, First, Second>
+ {
+ };
+
+ //===========================================================================
+ // Iterator Concepts
+
+ BOOST_concept(InputIterator,(TT))
+ : Assignable<TT>
+ , EqualityComparable<TT>
+ {
+ typedef typename std::iterator_traits<TT>::value_type value_type;
+ typedef typename std::iterator_traits<TT>::difference_type difference_type;
+ typedef typename std::iterator_traits<TT>::reference reference;
+ typedef typename std::iterator_traits<TT>::pointer pointer;
+ typedef typename std::iterator_traits<TT>::iterator_category iterator_category;
+
+ BOOST_CONCEPT_USAGE(InputIterator)
+ {
+ BOOST_CONCEPT_ASSERT((SignedInteger<difference_type>));
+ BOOST_CONCEPT_ASSERT((Convertible<iterator_category, std::input_iterator_tag>));
+
+ TT j(i);
+ (void)*i; // require dereference operator
+ ++j; // require preincrement operator
+ i++; // require postincrement operator
+ }
+ private:
+ TT i;
+ };
+
+ BOOST_concept(OutputIterator,(TT)(ValueT))
+ : Assignable<TT>
+ {
+ BOOST_CONCEPT_USAGE(OutputIterator) {
+
+ ++i; // require preincrement operator
+ i++; // require postincrement operator
+ *i++ = t; // require postincrement and assignment
+ }
+ private:
+ TT i, j;
+ ValueT t;
+ };
+
+ BOOST_concept(ForwardIterator,(TT))
+ : InputIterator<TT>
+ {
+ BOOST_CONCEPT_USAGE(ForwardIterator)
+ {
+ BOOST_CONCEPT_ASSERT((Convertible<
+ BOOST_DEDUCED_TYPENAME ForwardIterator::iterator_category
+ , std::forward_iterator_tag
+ >));
+
+ typename InputIterator<TT>::reference r = *i;
+ ignore_unused_variable_warning(r);
+ }
+
+ private:
+ TT i;
+ };
+
+ BOOST_concept(Mutable_ForwardIterator,(TT))
+ : ForwardIterator<TT>
+ {
+ BOOST_CONCEPT_USAGE(Mutable_ForwardIterator) {
+ *i++ = *j; // require postincrement and assignment
+ }
+ private:
+ TT i, j;
+ };
+
+ BOOST_concept(BidirectionalIterator,(TT))
+ : ForwardIterator<TT>
+ {
+ BOOST_CONCEPT_USAGE(BidirectionalIterator)
+ {
+ BOOST_CONCEPT_ASSERT((Convertible<
+ BOOST_DEDUCED_TYPENAME BidirectionalIterator::iterator_category
+ , std::bidirectional_iterator_tag
+ >));
+
+ --i; // require predecrement operator
+ i--; // require postdecrement operator
+ }
+ private:
+ TT i;
+ };
+
+ BOOST_concept(Mutable_BidirectionalIterator,(TT))
+ : BidirectionalIterator<TT>
+ , Mutable_ForwardIterator<TT>
+ {
+ BOOST_CONCEPT_USAGE(Mutable_BidirectionalIterator)
+ {
+ *i-- = *j; // require postdecrement and assignment
+ }
+ private:
+ TT i, j;
+ };
+
+ BOOST_concept(RandomAccessIterator,(TT))
+ : BidirectionalIterator<TT>
+ , Comparable<TT>
+ {
+ BOOST_CONCEPT_USAGE(RandomAccessIterator)
+ {
+ BOOST_CONCEPT_ASSERT((Convertible<
+ BOOST_DEDUCED_TYPENAME BidirectionalIterator<TT>::iterator_category
+ , std::random_access_iterator_tag
+ >));
+
+ 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
+ }
+
+ private:
+ TT a, b;
+ TT i, j;
+ typename std::iterator_traits<TT>::difference_type n;
+ };
+
+ BOOST_concept(Mutable_RandomAccessIterator,(TT))
+ : RandomAccessIterator<TT>
+ , Mutable_BidirectionalIterator<TT>
+ {
+ BOOST_CONCEPT_USAGE(Mutable_RandomAccessIterator)
+ {
+ i[n] = *i; // require element access and assignment
+ }
+ private:
+ TT i;
+ typename std::iterator_traits<TT>::difference_type n;
+ };
+
+ //===========================================================================
+ // Container s
+
+ BOOST_concept(Container,(C))
+ : Assignable<C>
+ {
+ typedef typename C::value_type value_type;
+ typedef typename C::difference_type difference_type;
+ typedef typename C::size_type size_type;
+ typedef typename C::const_reference const_reference;
+ typedef typename C::const_pointer const_pointer;
+ typedef typename C::const_iterator const_iterator;
+
+ BOOST_CONCEPT_USAGE(Container)
+ {
+ BOOST_CONCEPT_ASSERT((InputIterator<const_iterator>));
+ const_constraints(c);
+ }
+
+ private:
+ void const_constraints(const C& cc) {
+ i = cc.begin();
+ i = cc.end();
+ n = cc.size();
+ n = cc.max_size();
+ b = cc.empty();
+ }
+ C c;
+ bool b;
+ const_iterator i;
+ size_type n;
+ };
+
+ BOOST_concept(Mutable_Container,(C))
+ : Container<C>
+ {
+ typedef typename C::reference reference;
+ typedef typename C::iterator iterator;
+ typedef typename C::pointer pointer;
+
+ BOOST_CONCEPT_USAGE(Mutable_Container)
+ {
+ BOOST_CONCEPT_ASSERT((
+ Assignable<typename Mutable_Container::value_type>));
+
+ BOOST_CONCEPT_ASSERT((InputIterator<iterator>));
+
+ i = c.begin();
+ i = c.end();
+ c.swap(c2);
+ }
+
+ private:
+ iterator i;
+ C c, c2;
+ };
+
+ BOOST_concept(ForwardContainer,(C))
+ : Container<C>
+ {
+ BOOST_CONCEPT_USAGE(ForwardContainer)
+ {
+ BOOST_CONCEPT_ASSERT((
+ ForwardIterator<
+ typename ForwardContainer::const_iterator
+ >));
+ }
+ };
+
+ BOOST_concept(Mutable_ForwardContainer,(C))
+ : ForwardContainer<C>
+ , Mutable_Container<C>
+ {
+ BOOST_CONCEPT_USAGE(Mutable_ForwardContainer)
+ {
+ BOOST_CONCEPT_ASSERT((
+ Mutable_ForwardIterator<
+ typename Mutable_ForwardContainer::iterator
+ >));
+ }
+ };
+
+ BOOST_concept(ReversibleContainer,(C))
+ : ForwardContainer<C>
+ {
+ typedef typename
+ C::const_reverse_iterator
+ const_reverse_iterator;
+
+ BOOST_CONCEPT_USAGE(ReversibleContainer)
+ {
+ BOOST_CONCEPT_ASSERT((
+ BidirectionalIterator<
+ typename ReversibleContainer::const_iterator>));
+
+ BOOST_CONCEPT_ASSERT((BidirectionalIterator<const_reverse_iterator>));
+
+ const_constraints(c);
+ }
+ private:
+ void const_constraints(const C& cc)
+ {
+ const_reverse_iterator i = cc.rbegin();
+ i = cc.rend();
+ }
+ C c;
+ };
+
+ BOOST_concept(Mutable_ReversibleContainer,(C))
+ : Mutable_ForwardContainer<C>
+ , ReversibleContainer<C>
+ {
+ typedef typename C::reverse_iterator reverse_iterator;
+
+ BOOST_CONCEPT_USAGE(Mutable_ReversibleContainer)
+ {
+ typedef typename Mutable_ForwardContainer<C>::iterator iterator;
+ BOOST_CONCEPT_ASSERT((Mutable_BidirectionalIterator<iterator>));
+ BOOST_CONCEPT_ASSERT((Mutable_BidirectionalIterator<reverse_iterator>));
+
+ reverse_iterator i = c.rbegin();
+ i = c.rend();
+ }
+ private:
+ C c;
+ };
+
+ BOOST_concept(RandomAccessContainer,(C))
+ : ReversibleContainer<C>
+ {
+ typedef typename C::size_type size_type;
+ typedef typename C::const_reference const_reference;
+
+ BOOST_CONCEPT_USAGE(RandomAccessContainer)
+ {
+ BOOST_CONCEPT_ASSERT((
+ RandomAccessIterator<
+ typename RandomAccessContainer::const_iterator
+ >));
+
+ const_constraints(c);
+ }
+ private:
+ void const_constraints(const C& cc)
+ {
+ const_reference r = cc[n];
+ ignore_unused_variable_warning(r);
+ }
+
+ C c;
+ size_type n;
+ };
+
+ BOOST_concept(Mutable_RandomAccessContainer,(C))
+ : Mutable_ReversibleContainer<C>
+ , RandomAccessContainer<C>
+ {
+ private:
+ typedef Mutable_RandomAccessContainer self;
+ public:
+ BOOST_CONCEPT_USAGE(Mutable_RandomAccessContainer)
+ {
+ BOOST_CONCEPT_ASSERT((Mutable_RandomAccessIterator<typename self::iterator>));
+ BOOST_CONCEPT_ASSERT((Mutable_RandomAccessIterator<typename self::reverse_iterator>));
+
+ typename self::reference r = c[i];
+ ignore_unused_variable_warning(r);
+ }
+
+ private:
+ typename Mutable_ReversibleContainer<C>::size_type i;
+ C c;
+ };
+
+ // A Sequence is inherently mutable
+ BOOST_concept(Sequence,(S))
+ : Mutable_ForwardContainer<S>
+ // Matt Austern's book puts DefaultConstructible here, the C++
+ // standard places it in Container --JGS
+ // ... so why aren't we following the standard? --DWA
+ , DefaultConstructible<S>
+ {
+ BOOST_CONCEPT_USAGE(Sequence)
+ {
+ S
+ c(n, t),
+ c2(first, last);
+
+ c.insert(p, t);
+ c.insert(p, n, t);
+ c.insert(p, first, last);
+
+ c.erase(p);
+ c.erase(p, q);
+
+ typename Sequence::reference r = c.front();
+
+ ignore_unused_variable_warning(c);
+ ignore_unused_variable_warning(c2);
+ ignore_unused_variable_warning(r);
+ const_constraints(c);
+ }
+ private:
+ void const_constraints(const S& c) {
+ typename Sequence::const_reference r = c.front();
+ ignore_unused_variable_warning(r);
+ }
+
+ typename S::value_type t;
+ typename S::size_type n;
+ typename S::value_type* first, *last;
+ typename S::iterator p, q;
+ };
+
+ BOOST_concept(FrontInsertionSequence,(S))
+ : Sequence<S>
+ {
+ BOOST_CONCEPT_USAGE(FrontInsertionSequence)
+ {
+ c.push_front(t);
+ c.pop_front();
+ }
+ private:
+ S c;
+ typename S::value_type t;
+ };
+
+ BOOST_concept(BackInsertionSequence,(S))
+ : Sequence<S>
+ {
+ BOOST_CONCEPT_USAGE(BackInsertionSequence)
+ {
+ c.push_back(t);
+ c.pop_back();
+ typename BackInsertionSequence::reference r = c.back();
+ ignore_unused_variable_warning(r);
+ const_constraints(c);
+ }
+ private:
+ void const_constraints(const S& cc) {
+ typename BackInsertionSequence::const_reference
+ r = cc.back();
+ ignore_unused_variable_warning(r);
+ }
+ S c;
+ typename S::value_type t;
+ };
+
+ BOOST_concept(AssociativeContainer,(C))
+ : ForwardContainer<C>
+ , DefaultConstructible<C>
+ {
+ typedef typename C::key_type key_type;
+ typedef typename C::key_compare key_compare;
+ typedef typename C::value_compare value_compare;
+ typedef typename C::iterator iterator;
+
+ BOOST_CONCEPT_USAGE(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);
+ BOOST_CONCEPT_ASSERT((BinaryPredicate<key_compare,key_type,key_type>));
+
+ typedef typename AssociativeContainer::value_type value_type_;
+ BOOST_CONCEPT_ASSERT((BinaryPredicate<value_compare,value_type_,value_type_>));
+ }
+
+ // Redundant with the base concept, but it helps below.
+ typedef typename C::const_iterator const_iterator;
+ private:
+ void const_constraints(const C& cc)
+ {
+ ci = cc.find(k);
+ n = cc.count(k);
+ cr = cc.equal_range(k);
+ }
+
+ C c;
+ iterator i;
+ std::pair<iterator,iterator> r;
+ const_iterator ci;
+ std::pair<const_iterator,const_iterator> cr;
+ typename C::key_type k;
+ typename C::size_type n;
+ };
+
+ BOOST_concept(UniqueAssociativeContainer,(C))
+ : AssociativeContainer<C>
+ {
+ BOOST_CONCEPT_USAGE(UniqueAssociativeContainer)
+ {
+ C c(first, last);
+
+ pos_flag = c.insert(t);
+ c.insert(first, last);
+
+ ignore_unused_variable_warning(c);
+ }
+ private:
+ std::pair<typename C::iterator, bool> pos_flag;
+ typename C::value_type t;
+ typename C::value_type* first, *last;
+ };
+
+ BOOST_concept(MultipleAssociativeContainer,(C))
+ : AssociativeContainer<C>
+ {
+ BOOST_CONCEPT_USAGE(MultipleAssociativeContainer)
+ {
+ C c(first, last);
+
+ pos = c.insert(t);
+ c.insert(first, last);
+
+ ignore_unused_variable_warning(c);
+ ignore_unused_variable_warning(pos);
+ }
+ private:
+ typename C::iterator pos;
+ typename C::value_type t;
+ typename C::value_type* first, *last;
+ };
+
+ BOOST_concept(SimpleAssociativeContainer,(C))
+ : AssociativeContainer<C>
+ {
+ BOOST_CONCEPT_USAGE(SimpleAssociativeContainer)
+ {
+ typedef typename C::key_type key_type;
+ typedef typename C::value_type value_type;
+ BOOST_MPL_ASSERT((boost::is_same<key_type,value_type>));
+ }
+ };
+
+ BOOST_concept(PairAssociativeContainer,(C))
+ : AssociativeContainer<C>
+ {
+ BOOST_CONCEPT_USAGE(PairAssociativeContainer)
+ {
+ typedef typename C::key_type key_type;
+ typedef typename C::value_type value_type;
+ typedef typename C::mapped_type mapped_type;
+ typedef std::pair<const key_type, mapped_type> required_value_type;
+ BOOST_MPL_ASSERT((boost::is_same<value_type,required_value_type>));
+ }
+ };
+
+ BOOST_concept(SortedAssociativeContainer,(C))
+ : AssociativeContainer<C>
+ , ReversibleContainer<C>
+ {
+ BOOST_CONCEPT_USAGE(SortedAssociativeContainer)
+ {
+ C
+ 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);
+ const_constraints(c);
+ }
+
+ void const_constraints(const C& c)
+ {
+ kc = c.key_comp();
+ vc = c.value_comp();
+
+ cp = c.upper_bound(k);
+ cp = c.lower_bound(k);
+ cr = c.equal_range(k);
+ }
+
+ private:
+ typename C::key_compare kc;
+ typename C::value_compare vc;
+ typename C::value_type t;
+ typename C::key_type k;
+ typedef typename C::iterator iterator;
+ typedef typename C::const_iterator const_iterator;
+
+ typedef SortedAssociativeContainer self;
+ iterator p;
+ const_iterator cp;
+ std::pair<typename self::iterator,typename self::iterator> r;
+ std::pair<typename self::const_iterator,typename self::const_iterator> cr;
+ typename C::value_type* first, *last;
+ };
+
+ // HashedAssociativeContainer
+
+ BOOST_concept(Collection,(C))
+ {
+ BOOST_CONCEPT_USAGE(Collection)
+ {
+ boost::function_requires<boost::InputIteratorConcept<iterator> >();
+ boost::function_requires<boost::InputIteratorConcept<const_iterator> >();
+ boost::function_requires<boost::CopyConstructibleConcept<value_type> >();
+ const_constraints(c);
+ i = c.begin();
+ i = c.end();
+ c.swap(c);
+ }
+
+ void const_constraints(const C& cc) {
+ ci = cc.begin();
+ ci = cc.end();
+ n = cc.size();
+ b = cc.empty();
+ }
+
+ private:
+ typedef typename C::value_type value_type;
+ typedef typename C::iterator iterator;
+ typedef typename C::const_iterator const_iterator;
+ typedef typename C::reference reference;
+ typedef typename C::const_reference const_reference;
+ // typedef typename C::pointer pointer;
+ typedef typename C::difference_type difference_type;
+ typedef typename C::size_type size_type;
+
+ C c;
+ bool b;
+ iterator i;
+ const_iterator ci;
+ size_type n;
+ };
+} // namespace boost
+
+#if (defined _MSC_VER)
+# pragma warning( pop )
+#endif
+
+# include <boost/concept/detail/concept_undef.hpp>
+
+#endif // BOOST_CONCEPT_CHECKS_HPP
+
diff --git a/include/boost/concept_check/borland.hpp b/include/boost/concept_check/borland.hpp
new file mode 100644
index 0000000..107926b
--- /dev/null
+++ b/include/boost/concept_check/borland.hpp
@@ -0,0 +1,25 @@
+// Copyright David Abrahams 2006. 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)
+#ifndef BOOST_CONCEPT_CHECK_BORLAND_DWA2006429_HPP
+# define BOOST_CONCEPT_CHECK_BORLAND_DWA2006429_HPP
+
+namespace boost {
+
+template <class ModelFn>
+struct concept_check;
+
+template <class Model>
+struct concept_check<void(*)(Model)>
+{
+ enum { instantiate = sizeof((((Model*)0)->~Model()), 3) };
+};
+
+# define BOOST_CONCEPT_ASSERT( ModelInParens ) \
+ enum { BOOST_PP_CAT(boost_concept_check,__LINE__) = \
+ boost::concept_check<void(*)ModelInParens>::instantiate \
+ }
+
+} // namespace boost::concept_checking
+
+#endif // BOOST_CONCEPT_CHECK_BORLAND_DWA2006429_HPP
diff --git a/include/boost/concept_check/general.hpp b/include/boost/concept_check/general.hpp
new file mode 100644
index 0000000..cd09fb0
--- /dev/null
+++ b/include/boost/concept_check/general.hpp
@@ -0,0 +1,82 @@
+// Copyright David Abrahams 2006. 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)
+#ifndef BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP
+# define BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP
+
+# ifdef BOOST_OLD_CONCEPT_SUPPORT
+# include <boost/concept_check/has_constraints.hpp>
+# include <boost/mpl/if.hpp>
+# endif
+
+
+// This implementation works on GCC and Comeau, but has actually been
+// fairly carefully tuned to work on GCC versions starting with
+// gcc-2.95.x. If you're trying to get an additional compiler to pass
+// the tests you might consider breaking out a separate gcc.hpp and
+// starting over on the general case.
+namespace boost
+{
+ namespace concept_checking
+ {
+ template <void(*)()> struct instantiate {};
+ }
+
+ template <class ModelFn> struct concept_check_;
+
+ template <class Model>
+ void concept_check_failed()
+ {
+ ((Model*)0)->~Model();
+ }
+
+ template <class Model>
+ struct concept_check
+ {
+ concept_checking::instantiate<concept_check_failed<Model> > x;
+ enum { instantiate = 1 };
+ };
+
+# ifdef BOOST_OLD_CONCEPT_SUPPORT
+
+ template <class Model>
+ void constraint_check_failed()
+ {
+ ((Model*)0)->constraints();
+ }
+
+ template <class Model>
+ struct constraint_check
+ {
+ concept_checking::instantiate<constraint_check_failed<Model> > x;
+ enum { instantiate = 1 };
+ };
+
+ template <class Model>
+ struct concept_check_<void(*)(Model)>
+ : mpl::if_c<
+ concept_checking::has_constraints<Model>::value
+ , constraint_check<Model>
+ , concept_check<Model>
+ >::type
+ {};
+
+# else
+
+ template <class Model>
+ struct concept_check_<void(*)(Model)>
+ : concept_check<Model>
+ {};
+
+# endif
+
+ // Usage, in class or function context:
+ //
+ // BOOST_CONCEPT_ASSERT((UnaryFunctionConcept<F,bool,int>));
+# define BOOST_CONCEPT_ASSERT( ModelInParens ) \
+ enum { BOOST_PP_CAT(boost_concept_check,__LINE__) = \
+ ::boost::concept_check_<void(*) ModelInParens>::instantiate \
+ }
+}
+
+#endif // BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP
diff --git a/include/boost/concept_check/has_constraints.hpp b/include/boost/concept_check/has_constraints.hpp
new file mode 100644
index 0000000..e19f664
--- /dev/null
+++ b/include/boost/concept_check/has_constraints.hpp
@@ -0,0 +1,31 @@
+// Copyright David Abrahams 2006. 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)
+#ifndef BOOST_CONCEPT_CHECK_HAS_CONSTRAINTS_DWA2006429_HPP
+# define BOOST_CONCEPT_CHECK_HAS_CONSTRAINTS_DWA2006429_HPP
+
+namespace boost { namespace concept_checking {
+
+// Here we implement the "metafunction" that detects whether a
+// constraints metafunction exists
+typedef char yes;
+typedef char (&no)[2];
+
+template <class Model, void (Model::*)()>
+struct wrap_constraints {};
+
+template <class Model>
+inline yes has_constraints_(Model*, wrap_constraints<Model,&Model::constraints>* = 0);
+inline no has_constraints_(...);
+
+template <class Model>
+struct has_constraints
+{
+ BOOST_STATIC_CONSTANT(
+ bool
+ , value = sizeof( concept_checking::has_constraints_((Model*)0) ) == 1 );
+};
+
+}} // namespace boost::concept_checking
+
+#endif // BOOST_CONCEPT_CHECK_HAS_CONSTRAINTS_DWA2006429_HPP
diff --git a/include/boost/concept_check/msvc.hpp b/include/boost/concept_check/msvc.hpp
new file mode 100644
index 0000000..3968469
--- /dev/null
+++ b/include/boost/concept_check/msvc.hpp
@@ -0,0 +1,90 @@
+// Copyright David Abrahams 2006. 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)
+#ifndef BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP
+# define BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP
+
+# ifdef BOOST_OLD_CONCEPT_SUPPORT
+# include <boost/concept_check/has_constraints.hpp>
+# include <boost/mpl/if.hpp>
+# endif
+
+
+namespace boost
+{
+ namespace concept_checking
+ {
+ template <class Model>
+ struct concept_check_
+ {
+ virtual void failed(Model* x)
+ {
+ x->~Model();
+ }
+ };
+ }
+
+# ifdef BOOST_OLD_CONCEPT_SUPPORT
+
+ namespace concept_checking
+ {
+ template <class Model>
+ struct constraint_check
+ {
+ virtual void failed(Model* x)
+ {
+ x->constraints();
+ }
+ };
+ }
+
+ template <class Model>
+ struct concept_check
+ : mpl::if_c<
+ concept_checking::has_constraints<Model>::value
+ , concept_checking::constraint_check<Model>
+ , concept_checking::concept_check_<Model>
+ >::type
+ {};
+
+# else
+
+ template <class Model>
+ struct concept_check
+ : concept_checking::concept_check_<Model>
+ {};
+
+# endif
+
+# if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
+
+ //
+ // The iterator library sees some really strange errors unless we
+ // use partial specialization to extract the model type with
+ // msvc-7.1
+ //
+ template <class Model>
+ struct concept_check<void(*)(Model)>
+ : concept_check<Model>
+ { };
+
+# define BOOST_CONCEPT_ASSERT( ModelInParens ) \
+ enum { BOOST_PP_CAT(boost_concept_check,__LINE__) = \
+ sizeof(::boost::concept_check<void(*) ModelInParens>) \
+ }
+
+# else
+
+ template <class Model>
+ concept_check<Model>
+ concept_check_(void(*)(Model));
+
+# define BOOST_CONCEPT_ASSERT( ModelInParens ) \
+ enum { BOOST_PP_CAT(boost_concept_check,__LINE__) = \
+ sizeof(::boost::concept_check_((void(*) ModelInParens)0)) \
+ }
+
+# endif
+}
+
+#endif // BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP