Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r58041 - in trunk/boost/spirit: home home/karma home/karma/auto home/support home/support/auto include
From: hartmut.kaiser_at_[hidden]
Date: 2009-11-29 16:27:43


Author: hkaiser
Date: 2009-11-29 16:27:42 EST (Sun, 29 Nov 2009)
New Revision: 58041
URL: http://svn.boost.org/trac/boost/changeset/58041

Log:
Spirit: added karma::auto_ and related facilities
Added:
   trunk/boost/spirit/home/karma/auto/
   trunk/boost/spirit/home/karma/auto.hpp (contents, props changed)
   trunk/boost/spirit/home/karma/auto/auto.hpp (contents, props changed)
   trunk/boost/spirit/home/karma/auto/create_generator.hpp (contents, props changed)
   trunk/boost/spirit/home/karma/auto/meta_create.hpp (contents, props changed)
   trunk/boost/spirit/home/support/auto/
   trunk/boost/spirit/home/support/auto/meta_create.hpp (contents, props changed)
   trunk/boost/spirit/include/karma_auto.hpp (contents, props changed)
Text files modified:
   trunk/boost/spirit/home/karma.hpp | 1 +
   trunk/boost/spirit/home/support/common_terminals.hpp | 1 +
   2 files changed, 2 insertions(+), 0 deletions(-)

Modified: trunk/boost/spirit/home/karma.hpp
==============================================================================
--- trunk/boost/spirit/home/karma.hpp (original)
+++ trunk/boost/spirit/home/karma.hpp 2009-11-29 16:27:42 EST (Sun, 29 Nov 2009)
@@ -25,5 +25,6 @@
 #include <boost/spirit/home/karma/delimit_out.hpp>
 #include <boost/spirit/home/karma/what.hpp>
 #include <boost/spirit/home/karma/stream.hpp>
+#include <boost/spirit/home/karma/auto.hpp>
 
 #endif

Added: trunk/boost/spirit/home/karma/auto.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/auto.hpp 2009-11-29 16:27:42 EST (Sun, 29 Nov 2009)
@@ -0,0 +1,15 @@
+// Copyright (c) 2001-2009 Hartmut Kaiser
+//
+// 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)
+
+#if !defined(BOOST_SPIRIT_KARMA_AUTO_NOV_29_0324PM)
+#define BOOST_SPIRIT_KARMA_AUTO_NOV_29_0324PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/karma/auto/auto.hpp>
+
+#endif

Added: trunk/boost/spirit/home/karma/auto/auto.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/auto/auto.hpp 2009-11-29 16:27:42 EST (Sun, 29 Nov 2009)
@@ -0,0 +1,114 @@
+// Copyright (c) 2001-2009 Hartmut Kaiser
+//
+// 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)
+
+#if !defined(BOOST_SPIRIT_KARMA_STREAM_MAY_01_2007_0310PM)
+#define BOOST_SPIRIT_KARMA_STREAM_MAY_01_2007_0310PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/support/common_terminals.hpp>
+#include <boost/spirit/home/support/info.hpp>
+#include <boost/spirit/home/support/container.hpp>
+#include <boost/spirit/home/support/detail/hold_any.hpp>
+#include <boost/spirit/home/karma/domain.hpp>
+#include <boost/spirit/home/karma/meta_compiler.hpp>
+#include <boost/spirit/home/karma/delimit_out.hpp>
+#include <boost/spirit/home/karma/auto/create_generator.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Enablers
+ ///////////////////////////////////////////////////////////////////////////
+ template <>
+ struct use_terminal<karma::domain, tag::auto_> // enables auto_
+ : mpl::true_ {};
+}}
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace karma
+{
+ using spirit::auto_;
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Modifiers>
+ struct auto_generator
+ : primitive_generator<auto_generator<Modifiers> >
+ {
+ typedef mpl::int_<generator_properties::all_properties> properties;
+
+ template <typename Context, typename Unused>
+ struct attribute
+ {
+ typedef spirit::hold_any type;
+ };
+
+ auto_generator(Modifiers const& modifiers)
+ : modifiers_(modifiers) {}
+
+ template <
+ typename OutputIterator, typename Context, typename Delimiter
+ , typename Attribute, typename Expr>
+ bool generate_auto(OutputIterator& sink, Context& context
+ , Delimiter const& d, Attribute const& attr, Expr const& expr) const
+ {
+ return compile<karma::domain>(expr, modifiers_)
+ .generate(sink, context, d, attr);
+ }
+
+ // auto_generator has an attached attribute
+ template <
+ typename OutputIterator, typename Context, typename Delimiter
+ , typename Attribute>
+ bool generate(OutputIterator& sink, Context& context
+ , Delimiter const& d, Attribute const& attr) const
+ {
+ return generate_auto(sink, context, d, attr
+ , create_generator<Attribute>());
+ }
+
+ // this auto_generator has no attribute attached, it needs to have been
+ // initialized from a value/variable
+ template <typename OutputIterator, typename Context
+ , typename Delimiter>
+ static bool
+ generate(OutputIterator&, Context&, Delimiter const&, unused_type)
+ {
+ // It is not possible (doesn't make sense) to use auto_ generators
+ // without providing any attribute, as the generator doesn't 'know'
+ // what to output. The following assertion fires if this situation
+ // is detected in your code.
+ BOOST_SPIRIT_ASSERT_MSG(false, auto_not_usable_without_attribute, ());
+ return false;
+ }
+
+ template <typename Context>
+ info what(Context& /*context*/) const
+ {
+ return info("auto_");
+ }
+
+ Modifiers modifiers_;
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Generator generators: make_xxx function (objects)
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Modifiers>
+ struct make_primitive<tag::auto_, Modifiers>
+ {
+ typedef auto_generator<Modifiers> result_type;
+
+ result_type operator()(unused_type, Modifiers const& modifiers) const
+ {
+ return result_type(modifiers);
+ }
+ };
+}}}
+
+#endif

Added: trunk/boost/spirit/home/karma/auto/create_generator.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/auto/create_generator.hpp 2009-11-29 16:27:42 EST (Sun, 29 Nov 2009)
@@ -0,0 +1,42 @@
+// Copyright (c) 2001-2009 Hartmut Kaiser
+//
+// 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)
+
+#if !defined(BOOST_SPIRIT_KARMA_CREATE_NOV_21_2009_0340PM)
+#define BOOST_SPIRIT_KARMA_CREATE_NOV_21_2009_0340PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/karma/auto/meta_create.hpp>
+
+namespace boost { namespace spirit { namespace karma
+{
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T>
+ struct generator_creator
+ {
+ typedef spirit::meta_create<karma::domain, T> creator_type;
+ typedef typename proto::result_of::deep_copy<
+ typename creator_type::type
+ >::type type;
+
+ static type call()
+ {
+ return proto::deep_copy(creator_type::call());
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T>
+ typename generator_creator<T>::type
+ create_generator()
+ {
+ return generator_creator<T>::call();
+ }
+
+}}}
+
+#endif

Added: trunk/boost/spirit/home/karma/auto/meta_create.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/auto/meta_create.hpp 2009-11-29 16:27:42 EST (Sun, 29 Nov 2009)
@@ -0,0 +1,346 @@
+// Copyright (c) 2001-2009 Hartmut Kaiser
+//
+// 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)
+
+#if !defined(BOOST_SPIRIT_KARMA_META_CREATE_NOV_21_2009_0425PM)
+#define BOOST_SPIRIT_KARMA_META_CREATE_NOV_21_2009_0425PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/karma/domain.hpp>
+#include <boost/spirit/home/support/common_terminals.hpp>
+
+#include <boost/spirit/home/support/auto/meta_create.hpp>
+
+#include <boost/utility/enable_if.hpp>
+#include <boost/variant.hpp>
+#include <boost/optional.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace karma
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // compatible STL containers
+ template <typename Container>
+ struct meta_create_container
+ {
+ struct make_dereference
+ {
+ template <typename RT, typename T_>
+ static RT call(T_ const& t)
+ {
+ // we map STL containers to the Kleene star
+ return *t;
+ }
+ };
+
+ typedef spirit::detail::make_unary_proto_expr<
+ typename Container::value_type, proto::tag::dereference
+ , make_dereference, karma::domain
+ > make_proto_expr;
+
+ typedef typename make_proto_expr::type type;
+
+ static type call()
+ {
+ return make_proto_expr::call();
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // String types
+ template <typename String>
+ struct meta_create_string
+ {
+ typedef spirit::standard::string_type const& type;
+ static type call() { return spirit::standard::string; }
+ };
+
+ template <>
+ struct meta_create_string<wchar_t*>
+ {
+ typedef spirit::standard_wide::string_type const& type;
+ static type call() { return spirit::standard_wide::string; }
+ };
+
+ template <>
+ struct meta_create_string<wchar_t const*>
+ {
+ typedef spirit::standard_wide::string_type const& type;
+ static type call() { return spirit::standard_wide::string; }
+ };
+
+ template <int N>
+ struct meta_create_string<wchar_t[N]>
+ {
+ typedef spirit::standard_wide::string_type const& type;
+ static type call() { return spirit::standard_wide::string; }
+ };
+
+ template <int N>
+ struct meta_create_string<wchar_t const[N]>
+ {
+ typedef spirit::standard_wide::string_type const& type;
+ static type call() { return spirit::standard_wide::string; }
+ };
+
+ template <int N>
+ struct meta_create_string<wchar_t(&)[N]>
+ {
+ typedef spirit::standard_wide::string_type const& type;
+ static type call() { return spirit::standard_wide::string; }
+ };
+
+ template <int N>
+ struct meta_create_string<wchar_t const(&)[N]>
+ {
+ typedef spirit::standard_wide::string_type const& type;
+ static type call() { return spirit::standard_wide::string; }
+ };
+
+ template <typename Traits, typename Allocator>
+ struct meta_create_string<std::basic_string<wchar_t, Traits, Allocator> >
+ {
+ typedef spirit::standard_wide::string_type const& type;
+ static type call() { return spirit::standard_wide::string; }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Fusion sequences
+ template <typename Sequence>
+ struct meta_create_sequence
+ {
+ struct make_shift_left
+ {
+ template <typename RT, typename T1, typename T2>
+ static RT call(T1 const& t1, T2 const& t2)
+ {
+ return t1 << t2;
+ }
+ };
+
+ // create a mpl sequence from the given fusion sequence
+ typedef typename mpl::fold<
+ typename fusion::result_of::as_vector<Sequence>::type
+ , mpl::vector<>, mpl::push_back<mpl::_, mpl::_>
+ >::type sequence_type;
+
+ typedef spirit::detail::make_nary_proto_expr<
+ sequence_type, proto::tag::shift_left, make_shift_left, karma::domain
+ > make_proto_expr;
+
+ typedef typename make_proto_expr::type type;
+
+ static type call()
+ {
+ return make_proto_expr::call();
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // the default is to use the standard streaming operator unless it's a
+ // STL container or a fusion sequence
+ template <typename T, typename Enable = void>
+ struct meta_create_impl;
+
+ template <typename T>
+ struct meta_create_impl<T
+ , typename enable_if_c<
+ traits::is_container<T>::value && !traits::is_string<T>::value
+ >::type>
+ : meta_create_container<T> {};
+
+ template <typename T>
+ struct meta_create_impl<T
+ , typename enable_if<
+ traits::is_string<T>
+ >::type>
+ : meta_create_string<T> {};
+
+ template <typename T>
+ struct meta_create_impl<T
+ , typename enable_if<
+ fusion::traits::is_sequence<T>
+ >::type>
+ : meta_create_sequence<T> {};
+
+ template <typename T, typename Enable = void>
+ struct meta_create : meta_create_impl<T> {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ // optional
+ template <typename T>
+ struct meta_create<boost::optional<T> >
+ {
+ struct make_negate
+ {
+ template <typename RT, typename T_>
+ static RT call(T_ const& t)
+ {
+ return -t;
+ }
+ };
+
+ typedef spirit::detail::make_unary_proto_expr<
+ T, proto::tag::negate, make_negate, karma::domain
+ > make_proto_expr;
+
+ typedef typename make_proto_expr::type type;
+
+ static type call()
+ {
+ return make_proto_expr::call();
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // alternatives
+ template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
+ struct meta_create<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
+ {
+ struct make_bitwise_or
+ {
+ template <typename RT, typename T1_, typename T2_>
+ static RT call(T1_ const& t1, T2_ const& t2)
+ {
+ return t1 | t2;
+ }
+ };
+
+ typedef spirit::detail::make_nary_proto_expr<
+ typename boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types
+ , proto::tag::bitwise_or, make_bitwise_or, karma::domain
+ > make_proto_expr;
+
+ typedef typename make_proto_expr::type type;
+
+ static type call()
+ {
+ return make_proto_expr::call();
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // predefined specializations for primitive components
+
+ // character generator
+ template <>
+ struct meta_create<char>
+ {
+ typedef spirit::standard::char_type const& type;
+ static type call() { return spirit::standard::char_; }
+ };
+ template <>
+ struct meta_create<wchar_t>
+ {
+ typedef spirit::standard_wide::char_type const& type;
+ static type call() { return spirit::standard_wide::char_; }
+ };
+
+ // boolean generator
+ template <>
+ struct meta_create<bool>
+ {
+ typedef spirit::bool__type const& type;
+ static type call() { return spirit::bool_; }
+ };
+
+ // integral generators
+ template <>
+ struct meta_create<int>
+ {
+ typedef spirit::int__type const& type;
+ static type call() { return spirit::int_; }
+ };
+ template <>
+ struct meta_create<short>
+ {
+ typedef spirit::short__type const& type;
+ static type call() { return spirit::short_; }
+ };
+ template <>
+ struct meta_create<long>
+ {
+ typedef spirit::long__type const& type;
+ static type call() { return spirit::long_; }
+ };
+ template <>
+ struct meta_create<unsigned int>
+ {
+ typedef spirit::uint__type const& type;
+ static type call() { return spirit::uint_; }
+ };
+#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
+ template <>
+ struct meta_create<unsigned short>
+ {
+ typedef spirit::ushort__type const& type;
+ static type call() { return spirit::ushort_; }
+ };
+#endif
+ template <>
+ struct meta_create<unsigned long>
+ {
+ typedef spirit::ulong__type const& type;
+ static type call() { return spirit::ulong_; }
+ };
+
+#ifdef BOOST_HAS_LONG_LONG
+ template <>
+ struct meta_create<boost::long_long_type>
+ {
+ typedef spirit::long_long_type const& type;
+ static type call() { return spirit::long_long; }
+ };
+ template <>
+ struct meta_create<boost::ulong_long_type>
+ {
+ typedef spirit::ulong_long_type const& type;
+ static type call() { return spirit::ulong_long; }
+ };
+#endif
+
+ // floating point generators
+ template <>
+ struct meta_create<float>
+ {
+ typedef spirit::float__type const& type;
+ static type call() { return spirit::float_; }
+ };
+ template <>
+ struct meta_create<double>
+ {
+ typedef spirit::double__type const& type;
+ static type call() { return spirit::double_; }
+ };
+ template <>
+ struct meta_create<long double>
+ {
+ typedef spirit::long_double_type const& type;
+ static type call() { return spirit::long_double; }
+ };
+
+}}}
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit
+{
+ // dispatch this to the karma related specializations
+ template <typename T>
+ struct meta_create<karma::domain, T>
+ {
+ typedef typename spirit::detail::remove_const_ref<T>::type data_type;
+ typedef typename karma::meta_create<data_type>::type type;
+
+ static type call()
+ {
+ return karma::meta_create<data_type>::call();
+ }
+ };
+
+}}
+
+#endif

Added: trunk/boost/spirit/home/support/auto/meta_create.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/auto/meta_create.hpp 2009-11-29 16:27:42 EST (Sun, 29 Nov 2009)
@@ -0,0 +1,121 @@
+// Copyright (c) 2001-2009 Hartmut Kaiser
+//
+// 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)
+
+#if !defined(BOOST_SPIRIT_SUPPORT_META_CREATE_NOV_21_2009_0327PM)
+#define BOOST_SPIRIT_SUPPORT_META_CREATE_NOV_21_2009_0327PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/support/unused.hpp>
+
+#include <boost/type_traits/add_const.hpp>
+#include <boost/type_traits/add_reference.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+
+namespace boost { namespace spirit
+{
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Domain, typename Type, typename Char = char
+ , typename Enable = void>
+ struct meta_create;
+
+ ///////////////////////////////////////////////////////////////////////////
+ namespace detail
+ {
+ template <typename T>
+ struct add_const_ref
+ : add_reference<typename add_const<T>::type> {};
+
+ template <typename T>
+ struct remove_const_ref
+ : remove_const<typename remove_reference<T>::type> {};
+
+ ///////////////////////////////////////////////////////////////////////
+ template <typename T, typename OpTag, typename F, typename Domain>
+ struct make_unary_proto_expr
+ {
+ typedef spirit::meta_create<Domain, T> subject_type;
+
+ typedef proto::expr<
+ OpTag, proto::list1<
+ typename add_const_ref<typename subject_type::type>::type
+ >, 1
+ > type;
+
+ static type call()
+ {
+ return F::template call<type>(subject_type::call());
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////
+ template <typename OpTag, typename F, typename Domain>
+ struct nary_proto_expr_function
+ {
+ template <typename T>
+ struct result;
+
+ template <typename T1, typename T2>
+ struct result<nary_proto_expr_function(T1, T2)>
+ {
+ typedef typename
+ spirit::meta_create<Domain, T2>::type
+ right_type;
+
+ typedef typename mpl::if_<
+ traits::not_is_unused<typename remove_const_ref<T1>::type>
+ , proto::expr<
+ OpTag, proto::list2<
+ typename add_const_ref<T1>::type
+ , typename add_const_ref<right_type>::type
+ >, 2
+ >
+ , right_type
+ >::type type;
+ };
+
+ template <typename T>
+ typename result<nary_proto_expr_function(unused_type const&, T)>::type
+ operator()(unused_type const&, T) const
+ {
+ typedef spirit::meta_create<Domain, T> type;
+ return type::call();
+ }
+
+ template <typename T1, typename T2>
+ typename result<nary_proto_expr_function(T1, T2)>::type
+ operator()(T1 const& t1, T2) const
+ {
+ // we variants to the alternative operator
+ typedef spirit::meta_create<Domain, T2>
+ right_type;
+ typedef typename result<nary_proto_expr_function(T1, T2)>::type
+ return_type;
+
+ return F::template call<return_type>(t1, right_type::call());
+ }
+ };
+
+ template <typename Sequence, typename OpTag, typename F, typename Domain>
+ struct make_nary_proto_expr
+ {
+ typedef nary_proto_expr_function<OpTag, F, Domain> make_proto_expr;
+
+ typedef typename fusion::result_of::fold<
+ Sequence, unused_type, make_proto_expr
+ >::type type;
+
+ static type call()
+ {
+ return fusion::fold(Sequence(), unused, make_proto_expr());
+ }
+ };
+ }
+}}
+
+#endif

Modified: trunk/boost/spirit/home/support/common_terminals.hpp
==============================================================================
--- trunk/boost/spirit/home/support/common_terminals.hpp (original)
+++ trunk/boost/spirit/home/support/common_terminals.hpp 2009-11-29 16:27:42 EST (Sun, 29 Nov 2009)
@@ -33,6 +33,7 @@
         ( buffer )
         ( true_ )
         ( false_ )
+ ( auto_ )
     )
 
     // Here we are reusing proto::lit

Added: trunk/boost/spirit/include/karma_auto.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/include/karma_auto.hpp 2009-11-29 16:27:42 EST (Sun, 29 Nov 2009)
@@ -0,0 +1,18 @@
+/*=============================================================================
+ Copyright (c) 2001-2009 Joel de Guzman
+ Copyright (c) 2001-2009 Hartmut Kaiser
+ http://spirit.sourceforge.net/
+
+ 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_SPIRIT_INCLUDE_KARMA_AUTO
+#define BOOST_SPIRIT_INCLUDE_KARMA_AUTO
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/karma/auto.hpp>
+
+#endif


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