Squashed 'third_party/boostorg/detail/' content from commit 824721a

Change-Id: Id58ef7955aa7ca41b9e6b3f41ee1b0ad900985ea
git-subtree-dir: third_party/boostorg/detail
git-subtree-split: 824721a7533de893338ed5bbc8e8d9f4fb1ad716
diff --git a/include/boost/detail/named_template_params.hpp b/include/boost/detail/named_template_params.hpp
new file mode 100644
index 0000000..e7cb079
--- /dev/null
+++ b/include/boost/detail/named_template_params.hpp
@@ -0,0 +1,177 @@
+// (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>
+#endif
+
+namespace 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