$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r73008 - in sandbox/coerce: boost/coerce boost/coerce/detail libs/coerce/example
From: vexocide_at_[hidden]
Date: 2011-07-11 18:37:08
Author: vexocide
Date: 2011-07-11 18:37:08 EDT (Mon, 11 Jul 2011)
New Revision: 73008
URL: http://svn.boost.org/trac/boost/changeset/73008
Log:
Added an initial implementation of tags
Added:
   sandbox/coerce/boost/coerce/tag.hpp   (contents, props changed)
Text files modified: 
   sandbox/coerce/boost/coerce/coerce.hpp         |    41 +++++++++++++++++++++++----             
   sandbox/coerce/boost/coerce/detail/karma.hpp   |    58 +++++++++++++++++++++++++++++++++++++-- 
   sandbox/coerce/boost/coerce/detail/qi.hpp      |    22 +++++++++++++-                          
   sandbox/coerce/libs/coerce/example/backend.cpp |     5 ++-                                     
   4 files changed, 111 insertions(+), 15 deletions(-)
Modified: sandbox/coerce/boost/coerce/coerce.hpp
==============================================================================
--- sandbox/coerce/boost/coerce/coerce.hpp	(original)
+++ sandbox/coerce/boost/coerce/coerce.hpp	2011-07-11 18:37:08 EDT (Mon, 11 Jul 2011)
@@ -14,8 +14,12 @@
 #include <boost/coerce/detail/backend.hpp>
 #include <boost/coerce/sequence.hpp>
 #include <boost/coerce/string.hpp>
+#include <boost/coerce/tag.hpp>
 
+#include <boost/config.hpp>
 #include <boost/throw_exception.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/utility/enable_if.hpp>
 
 #include <typeinfo>  // for std::bad_cast
 
@@ -23,7 +27,12 @@
 
     namespace traits {
 
-        template <typename Target, typename Source, typename Enable = void>
+        template <
+            typename Target
+          , typename Source
+          , typename Tag
+          , typename Enable = void
+        >
         struct as
             : detail::backend<
                 typename traits::is_sequence<Target>::type,
@@ -35,14 +44,14 @@
     class bad_cast
         : public std::bad_cast { };
 
-    template <typename Target, typename Source>
+    template <typename Target, typename Source, typename Tag>
     inline Target
-    as(Source const & source) {
+    as(Source const & source, Tag const & tag) {
         Target target;
 
         bool result = traits::as<
-                Target, Source
-            >::call(target, source);
+                Target, Source, Tag
+            >::BOOST_NESTED_TEMPLATE call<Target, Source, Tag>(target, source);
 
         if (!result) {
             throw_exception(coerce::bad_cast());
@@ -53,15 +62,23 @@
 
     template <typename Target, typename Source>
     inline Target
+    as(Source const & source) {
+        return as<Target, Source, tag::none>(source, tag::none());
+    }
+
+    template <typename Target, typename Source, typename Tag>
+    inline typename disable_if<
+        is_same<Target, Tag>, Target>::type
     as_default(
         Source const & source,
+        Tag const & tag,
         Target const & default_value = Target()
     ) {
         Target target;
 
         bool result = traits::as<
-                Target, Source
-            >::call(target, source);
+                Target, Source, Tag
+            >::BOOST_NESTED_TEMPLATE call<Target, Source, Tag>(target, source);
 
         if (!result) {
             return default_value;
@@ -70,6 +87,16 @@
         return target;
     }
 
+    template <typename Target, typename Source>
+    inline Target
+    as_default(
+        Source const & source,
+        Target const & default_value = Target()
+    ) {
+        return as_default<Target, Source, tag::none>(
+            source, tag::none(), default_value);
+    }
+
 } }  // namespace boost::coerce
 
 #endif  // BOOST_COERCE_COERCE_HPP
Modified: sandbox/coerce/boost/coerce/detail/karma.hpp
==============================================================================
--- sandbox/coerce/boost/coerce/detail/karma.hpp	(original)
+++ sandbox/coerce/boost/coerce/detail/karma.hpp	2011-07-11 18:37:08 EDT (Mon, 11 Jul 2011)
@@ -13,17 +13,69 @@
 
 #include <boost/coerce/reserve.hpp>
 #include <boost/coerce/sequence.hpp>
+#include <boost/coerce/tag.hpp>
 
+#include <boost/config.hpp>
+#include <boost/limits.hpp>
 #include <boost/spirit/home/karma/auto.hpp>
 #include <boost/spirit/home/karma/char.hpp>
 #include <boost/spirit/home/karma/numeric.hpp>
 #include <boost/spirit/home/karma/operator/optional.hpp>
 #include <boost/spirit/include/version.hpp>
+#include <boost/type_traits/remove_const.hpp>
 
 namespace boost { namespace coerce { namespace detail {
 
+    template <typename Source, typename Tag>
+    struct create_generator {
+        typedef typename Tag::BOOST_NESTED_TEMPLATE generator<Source>::type type;
+
+        static inline type const
+        call() {
+            return Tag::BOOST_NESTED_TEMPLATE generator<Source>::call();
+        }
+    };
+
+    template <typename Source>
+    struct create_generator<Source, tag::none>
+        : spirit::traits::create_generator<Source> { };
+
+    template <typename Source>
+    struct real_policies
+        : spirit::karma::real_policies<Source> {
+        static inline unsigned
+        precision(Source const &) {
+            return std::numeric_limits<Source>::digits10 + 1;
+        }
+    };
+
+    template <typename Source>
+    struct create_generator_floating_point {
+        typedef spirit::karma::real_generator<
+            Source,
+            real_policies<typename remove_const<Source>::type>
+        > type;
+
+        static inline type const
+        call() {
+            return type();
+        }
+    }; 
+
+    template <>
+    struct create_generator<float, tag::none>
+        : create_generator_floating_point<float> { };
+
+    template <>
+    struct create_generator<double, tag::none>
+        : create_generator_floating_point<double> { };
+
+    template <>
+    struct create_generator<long double, tag::none>
+        : create_generator_floating_point<long double> { };
+
     struct karma {
-        template <typename Target, typename Source>
+        template <typename Target, typename Source, typename Tag>
         static inline bool
         call(Target & target, Source const & source) {
             detail::call_reserve(
@@ -31,9 +83,7 @@
 
             bool result = spirit::karma::generate(
                 traits::sequence<Target>::back_inserter(target),
-#if SPIRIT_VERSION <= 0x2030
-                spirit::karma::auto_,
-#endif
+                create_generator<Source, Tag>::call(),
                 source);
 
             return result; 
Modified: sandbox/coerce/boost/coerce/detail/qi.hpp
==============================================================================
--- sandbox/coerce/boost/coerce/detail/qi.hpp	(original)
+++ sandbox/coerce/boost/coerce/detail/qi.hpp	2011-07-11 18:37:08 EDT (Mon, 11 Jul 2011)
@@ -13,7 +13,9 @@
 
 #include <boost/coerce/reserve.hpp>
 #include <boost/coerce/string.hpp>
+#include <boost/coerce/tag.hpp>
 
+#include <boost/config.hpp>
 #include <boost/spirit/home/qi/auto.hpp>
 #include <boost/spirit/home/qi/char.hpp>
 #include <boost/spirit/home/qi/numeric.hpp>
@@ -21,8 +23,22 @@
 
 namespace boost { namespace coerce { namespace detail {
 
+    template <typename Target, typename Tag>
+    struct create_parser {
+        typedef typename Tag::BOOST_NESTED_TEMPLATE parser<Target>::type type;
+
+        static inline type const
+        call() {
+            return Tag::BOOST_NESTED_TEMPLATE parser<Target>::call();
+        }
+    };
+
+    template <typename Target>
+    struct create_parser<Target, tag::none>
+        : spirit::traits::create_parser<Target> { };
+
     struct qi {
-        template <typename Target, typename Source>
+        template <typename Target, typename Source, typename Tag>
         static inline bool
         call(Target & target, Source const & source) {
             typedef traits::string<Source> string_traits;
@@ -35,7 +51,9 @@
                 begin = string_traits::begin(source), iterator = begin;
 
             bool result = spirit::qi::parse(
-                iterator, string_traits::end(source), target);
+                iterator, string_traits::end(source),
+                create_parser<Target, Tag>::call(),
+                target);
 
             if (static_cast<typename string_traits::size_type>(iterator - begin) != length) {
                 return false;
Added: sandbox/coerce/boost/coerce/tag.hpp
==============================================================================
--- (empty file)
+++ sandbox/coerce/boost/coerce/tag.hpp	2011-07-11 18:37:08 EDT (Mon, 11 Jul 2011)
@@ -0,0 +1,61 @@
+//              Copyright Jeroen Habraken 2011.
+//
+// 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_COERCE_TAG_HPP
+#define BOOST_COERCE_TAG_HPP
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <boost/mpl/if.hpp>
+#include <boost/spirit/home/karma/numeric.hpp>
+#include <boost/spirit/home/qi/numeric.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_integral.hpp>
+#include <boost/type_traits/is_signed.hpp>
+
+namespace boost { namespace coerce { namespace tag {
+
+    struct none { };
+
+    struct bin {
+        template <typename Target>
+        struct parser {
+            BOOST_STATIC_ASSERT(is_integral<Target>::value);
+
+            typedef typename mpl::if_<
+                is_signed<Target>,
+                spirit::qi::int_parser<Target, 2>,
+                spirit::qi::uint_parser<Target, 2>
+            >::type type;
+                
+            static inline type const
+            call() {
+                return type();
+            }
+        };
+
+        template <typename Source>
+        struct generator {
+            BOOST_STATIC_ASSERT(is_integral<Source>::value);
+
+            typedef typename mpl::if_<
+                is_signed<Source>,
+                spirit::karma::int_generator<Source, 2>,
+                spirit::karma::uint_generator<Source, 2>
+            >::type type;
+
+            static inline type const
+            call() {
+                return type();
+            }
+        };
+    };
+
+} } }  // namespace boost::coerce::tag
+
+#endif  // BOOST_COERCE_TAG_HPP
Modified: sandbox/coerce/libs/coerce/example/backend.cpp
==============================================================================
--- sandbox/coerce/libs/coerce/example/backend.cpp	(original)
+++ sandbox/coerce/libs/coerce/example/backend.cpp	2011-07-11 18:37:08 EDT (Mon, 11 Jul 2011)
@@ -5,13 +5,14 @@
 //          http://www.boost.org/LICENSE_1_0.txt)
 
 #include <boost/coerce.hpp>
+#include <boost/spirit/include/support_unused.hpp>
 
 #include <cerrno>  // for errno
 #include <cstdio>  // for std::strtol
 #include <iostream>
 
 struct strtol {
-    template <typename Target, typename Source>
+    template <typename Target, typename Source, typename Tag>
     static inline bool
     call(Target & target, Source const & source) {
         target = std::strtol(source, NULL, 10);
@@ -23,7 +24,7 @@
 namespace boost { namespace coerce { namespace traits {
 
     template <std::size_t N>
-    struct as<long int, char [N]>
+    struct as<long int, char [N], spirit::unused_type>
         : strtol { };
 
 } } }  // namespace boost::coerce::traits