| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 | // (C) Copyright Jeremy Siek 2001.// 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:// 04 Oct 2001   David Abrahams//      Changed name of "bind" to "select" to avoid problems with MSVC.#ifndef BOOST_DETAIL_NAMED_TEMPLATE_PARAMS_HPP#define BOOST_DETAIL_NAMED_TEMPLATE_PARAMS_HPP#include <boost/type_traits/conversion_traits.hpp>#include <boost/type_traits/composite_traits.hpp> // for is_reference#if defined(__BORLANDC__)#include <boost/type_traits/ice.hpp>#endifnamespace boost {  namespace detail {        struct default_argument { };    struct dummy_default_gen {      template <class Base, class Traits>      struct select {        typedef default_argument type;      };    };   // This class template is a workaround for MSVC.   template <class Gen> struct default_generator {     typedef detail::dummy_default_gen type;   };    template <class T> struct is_default {       enum { value = false };        typedef type_traits::no_type type;    };    template <> struct is_default<default_argument> {       enum { value = true };       typedef type_traits::yes_type type;    };    struct choose_default {      template <class Arg, class DefaultGen, class Base, class Traits>      struct select {        typedef typename default_generator<DefaultGen>::type Gen;        typedef typename Gen::template select<Base,Traits>::type type;      };    };    struct choose_arg {      template <class Arg, class DefaultGen, class Base, class Traits>      struct select {        typedef Arg type;      };    };#if defined(__BORLANDC__)    template <class UseDefault>    struct choose_arg_or_default { typedef choose_arg type; };    template <>    struct choose_arg_or_default<type_traits::yes_type> {      typedef choose_default type;    };#else    template <bool UseDefault>    struct choose_arg_or_default { typedef choose_arg type; };    template <>    struct choose_arg_or_default<true> {      typedef choose_default type;    };#endif        template <class Arg, class DefaultGen, class Base, class Traits>    class resolve_default {#if defined(__BORLANDC__)      typedef typename choose_arg_or_default<typename is_default<Arg>::type>::type Selector;#else      // This usually works for Borland, but I'm seeing weird errors in      // iterator_adaptor_test.cpp when using this method.      enum { is_def = is_default<Arg>::value };      typedef typename choose_arg_or_default<is_def>::type Selector;#endif    public:      typedef typename Selector        ::template select<Arg, DefaultGen, Base, Traits>::type type;    };    // To differentiate an unnamed parameter from a traits generator    // we use is_convertible<X, iter_traits_gen_base>.    struct named_template_param_base { };    template <class X>    struct is_named_param_list {      enum { value  = is_convertible<X, named_template_param_base>::value };    };        struct choose_named_params {      template <class Prev> struct select { typedef Prev type; };    };    struct choose_default_arg {      template <class Prev> struct select {         typedef detail::default_argument type;      };    };    template <bool Named> struct choose_default_dispatch_;    template <> struct choose_default_dispatch_<true> {      typedef choose_named_params type;    };    template <> struct choose_default_dispatch_<false> {      typedef choose_default_arg type;    };    // The use of inheritance here is a Solaris Forte 6 workaround.    template <bool Named> struct choose_default_dispatch      : public choose_default_dispatch_<Named> { };    template <class PreviousArg>    struct choose_default_argument {      enum { is_named = is_named_param_list<PreviousArg>::value };      typedef typename choose_default_dispatch<is_named>::type Selector;      typedef typename Selector::template select<PreviousArg>::type type;    };    // This macro assumes that there is a class named default_##TYPE    // defined before the application of the macro.  This class should    // have a single member class template named "select" with two    // template parameters: the type of the class being created (e.g.,    // the iterator_adaptor type when creating iterator adaptors) and    // a traits class. The select class should have a single typedef    // named "type" that produces the default for TYPE.  See    // boost/iterator_adaptors.hpp for an example usage.  Also,    // applications of this macro must be placed in namespace    // boost::detail.#define BOOST_NAMED_TEMPLATE_PARAM(TYPE) \    struct get_##TYPE##_from_named { \      template <class Base, class NamedParams, class Traits> \      struct select { \          typedef typename NamedParams::traits NamedTraits; \          typedef typename NamedTraits::TYPE TYPE; \          typedef typename resolve_default<TYPE, \            default_##TYPE, Base, NamedTraits>::type type; \      }; \    }; \    struct pass_thru_##TYPE { \      template <class Base, class Arg, class Traits> struct select { \          typedef typename resolve_default<Arg, \            default_##TYPE, Base, Traits>::type type; \      };\    }; \    template <int NamedParam> \    struct get_##TYPE##_dispatch { }; \    template <> struct get_##TYPE##_dispatch<1> { \      typedef get_##TYPE##_from_named type; \    }; \    template <> struct get_##TYPE##_dispatch<0> { \      typedef pass_thru_##TYPE type; \    }; \    template <class Base, class X, class Traits>  \    class get_##TYPE { \      enum { is_named = is_named_param_list<X>::value }; \      typedef typename get_##TYPE##_dispatch<is_named>::type Selector; \    public: \      typedef typename Selector::template select<Base, X, Traits>::type type; \    }; \    template <> struct default_generator<default_##TYPE> { \      typedef default_##TYPE type; \    }      } // namespace detail} // namespace boost#endif // BOOST_DETAIL_NAMED_TEMPLATE_PARAMS_HPP
 |