|
Boost-Commit : |
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
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk