// (C) Copyright 2008-2009 SDML (www.sdml.info) // // Use, modification and distribution is subject to 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) #include #include #include #include // #include using namespace origin; using std::cout; // NOTE: // Q: How do you make an archetype for a classifying or explicit concept? // A: Define a concept map. template < typename Iter, typename T, typename = typename concept_assert< ObjectType, HasEqualTo >::type> void foo(Iter f, Iter l, T const& x) { } // These are archetypes from type concepts. struct TypenameArchetype { protected: TypenameArchetype() { } TypenameArchetype(TypenameArchetype&&) { } TypenameArchetype(TypenameArchetype const&) { } ~TypenameArchetype() { } }; struct ObjectTypeArchetype : TypenameArchetype { }; // We need to specify that ObjectTypeArchetype actually models ObjectType or // we run into some specification issues. namespace origin { template <> struct ObjectType : Tautology , ReferentType , PointeeType { ORIGIN_CONCEPT_MAP_IMPL(); }; }; // This is the archetype system for the foo algorithm. namespace foo_Archetypes { // Define a new archetype for each template parameter by deriving from the // archetype for its "primary" model. Ideally, the primary model is // requirement declared with shorthand notation (e.g., ObjectType Iter or // typename T). struct IterArchetype : ObjectTypeArchetype { }; struct TArchetype : ::TypenameArchetype { }; // NOTE: If the base archetype hides any special functions (ctors, dtors) // that can be geneated by the compiler, then the derived class must also // hide or delete them. Otherwise, we would allow new features to creep // into the archetype system. // NOTE: We need a better term for the "primary" model. It's really the // declared model of the template parameter. I like that. Declared model. // If any of these archetypes declare free functions (e.g., swap, or // source), then you have to redeclare them in this scope because // ADL doesn't play with inheritance, to my knowledge. // NOTE: // Q: What if a template parameter has no declared model? For example a // function add(a, b) requires HasAdd, but that's about it. // A: The process should be the same. The declared model is typename, and // the HasAdd archetypee // We still have to generate an archetype for the binary or bridging // concept in case the algorithm tries to pull the result type. An i struct HasAddArchetype { typedef bool result_type; }; // Define the free function requirement of HasEqualTo. bool operator==(IterArchetype const&, TArchetype const&) { return value(); } // NOTE: // Q: What about concepts with deduced typenames? // A: Not entirely sure. If the deduced typename is unmodified (i.e., // typename) then we can just return a TypenameArchetype. If there are // other constraints on the typename, either from the declaring concept or // applied via the function requirements then we would generate a new // archetype to encapsulate it. }; int main() { foo_Archetypes::IterArchetype const& f = value(); foo_Archetypes::IterArchetype const& l = value(); foo_Archetypes::TArchetype const& x = value(); foo(f, l, x); return 0; }