Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-19 09:47:36

0001 //  Copyright (c) 2001-2011 Hartmut Kaiser
0002 //
0003 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
0004 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0005 
0006 #ifndef BOOST_SPIRIT_KARMA_DIRECTIVE_DUPLICATE_HPP
0007 #define BOOST_SPIRIT_KARMA_DIRECTIVE_DUPLICATE_HPP
0008 
0009 #if defined(_MSC_VER)
0010 #pragma once
0011 #endif
0012 
0013 #include <boost/spirit/home/karma/meta_compiler.hpp>
0014 #include <boost/spirit/home/karma/generator.hpp>
0015 #include <boost/spirit/home/karma/domain.hpp>
0016 #include <boost/spirit/home/karma/detail/attributes.hpp>
0017 #include <boost/spirit/home/support/unused.hpp>
0018 #include <boost/spirit/home/support/info.hpp>
0019 #include <boost/spirit/home/support/common_terminals.hpp>
0020 #include <boost/spirit/home/support/assert_msg.hpp>
0021 #include <boost/spirit/home/support/has_semantic_action.hpp>
0022 #include <boost/spirit/home/support/handles_container.hpp>
0023 #include <boost/fusion/include/cons.hpp>
0024 #include <boost/fusion/include/make_cons.hpp>
0025 #include <boost/fusion/include/vector.hpp>
0026 #include <boost/fusion/include/at_c.hpp>
0027 #include <boost/mpl/identity.hpp>
0028 #include <boost/mpl/bool.hpp>
0029 
0030 namespace boost { namespace spirit
0031 {
0032     ///////////////////////////////////////////////////////////////////////////
0033     // Enablers
0034     ///////////////////////////////////////////////////////////////////////////
0035     template <>
0036     struct use_directive<karma::domain, tag::duplicate> // enables duplicate
0037       : mpl::true_ {};
0038 }}
0039 
0040 namespace boost { namespace spirit { namespace karma
0041 {
0042 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
0043     using spirit::duplicate;
0044 #endif
0045     using spirit::duplicate_type;
0046 
0047     ///////////////////////////////////////////////////////////////////////////
0048     namespace detail
0049     {
0050         ///////////////////////////////////////////////////////////////////////
0051         template <typename T
0052           , bool IsSequence = fusion::traits::is_sequence<T>::value>
0053         struct attribute_count
0054           : fusion::result_of::size<T>
0055         {};
0056 
0057         template <>
0058         struct attribute_count<unused_type, false>
0059           : mpl::int_<0>
0060         {};
0061 
0062         template <typename T>
0063         struct attribute_count<T, false>
0064           : mpl::int_<1>
0065         {};
0066 
0067         ///////////////////////////////////////////////////////////////////////
0068         template <typename T
0069           , bool IsSequence = fusion::traits::is_sequence<T>::value>
0070         struct first_attribute_of_subject
0071           : remove_reference<typename fusion::result_of::at_c<T, 0>::type>
0072         {};
0073 
0074         template <typename T>
0075         struct first_attribute_of_subject<T, false>
0076           : mpl::identity<T>
0077         {};
0078 
0079         template <typename T, typename Context, typename Iterator>
0080         struct first_attribute_of
0081           : first_attribute_of_subject<
0082                 typename traits::attribute_of<T, Context, Iterator>::type>
0083         {};
0084 
0085         ///////////////////////////////////////////////////////////////////////
0086         template <typename Attribute, typename T, int N>
0087         struct duplicate_sequence_attribute
0088         {
0089             typedef typename fusion::result_of::make_cons<
0090                 reference_wrapper<T const>
0091               , typename duplicate_sequence_attribute<Attribute, T, N-1>::type
0092             >::type type;
0093 
0094             static type call(T const& t)
0095             {
0096                 return fusion::make_cons(boost::cref(t)
0097                   , duplicate_sequence_attribute<Attribute, T, N-1>::call(t));
0098             }
0099         };
0100 
0101         template <typename Attribute, typename T>
0102         struct duplicate_sequence_attribute<Attribute, T, 1>
0103         {
0104             typedef typename fusion::result_of::make_cons<
0105                 reference_wrapper<T const> >::type type;
0106 
0107             static type call(T const& t)
0108             {
0109                 return fusion::make_cons(boost::cref(t));
0110             }
0111         };
0112 
0113         ///////////////////////////////////////////////////////////////////////
0114         template <typename Attribute, typename T
0115           , int N = attribute_count<Attribute>::value
0116           , bool IsSequence = fusion::traits::is_sequence<Attribute>::value>
0117         struct duplicate_attribute
0118         {
0119             BOOST_SPIRIT_ASSERT_MSG(N > 0, invalid_duplication_count, (Attribute));
0120 
0121             typedef typename duplicate_sequence_attribute<Attribute, T, N>::type
0122                 cons_type;
0123             typedef typename fusion::result_of::as_vector<cons_type>::type type;
0124 
0125             static type call(T const& t)
0126             {
0127                 return fusion::as_vector(
0128                     duplicate_sequence_attribute<Attribute, T, N>::call(t));
0129             }
0130         };
0131 
0132         template <typename Attribute, typename T>
0133         struct duplicate_attribute<Attribute, T, 0, false>
0134         {
0135             typedef unused_type type;
0136 
0137             static type call(T const&)
0138             {
0139                 return unused;
0140             }
0141         };
0142 
0143         template <typename Attribute, typename T, int N>
0144         struct duplicate_attribute<Attribute, T, N, false>
0145         {
0146             typedef Attribute const& type;
0147 
0148             static type call(T const& t)
0149             {
0150                 return t;
0151             }
0152         };
0153     }
0154 
0155     template <typename Attribute, typename T>
0156     inline typename detail::duplicate_attribute<Attribute, T>::type
0157     duplicate_attribute(T const& t)
0158     {
0159         return detail::duplicate_attribute<Attribute, T>::call(t);
0160     }
0161 
0162     ///////////////////////////////////////////////////////////////////////////
0163     // duplicate_directive duplicate its attribute for all elements of the
0164     // subject generator without generating anything itself
0165     ///////////////////////////////////////////////////////////////////////////
0166     template <typename Subject>
0167     struct duplicate_directive : unary_generator<duplicate_directive<Subject> >
0168     {
0169         typedef Subject subject_type;
0170         typedef typename subject_type::properties properties;
0171 
0172         duplicate_directive(Subject const& subject)
0173           : subject(subject) {}
0174 
0175         template <typename Context, typename Iterator = unused_type>
0176         struct attribute
0177           : detail::first_attribute_of<Subject, Context, Iterator>
0178         {};
0179 
0180         template <typename OutputIterator, typename Context, typename Delimiter
0181           , typename Attribute>
0182         bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
0183           , Attribute const& attr) const
0184         {
0185             typedef typename traits::attribute_of<Subject, Context>::type
0186                 subject_attr_type;
0187             return subject.generate(sink, ctx, d
0188               , duplicate_attribute<subject_attr_type>(attr));
0189         }
0190 
0191         template <typename Context>
0192         info what(Context& context) const
0193         {
0194             return info("duplicate", subject.what(context));
0195         }
0196 
0197         Subject subject;
0198     };
0199 
0200     ///////////////////////////////////////////////////////////////////////////
0201     // Generator generators: make_xxx function (objects)
0202     ///////////////////////////////////////////////////////////////////////////
0203     template <typename Subject, typename Modifiers>
0204     struct make_directive<tag::duplicate, Subject, Modifiers>
0205     {
0206         typedef duplicate_directive<Subject> result_type;
0207         result_type operator()(unused_type, Subject const& subject
0208           , unused_type) const
0209         {
0210             return result_type(subject);
0211         }
0212     };
0213 }}}
0214 
0215 namespace boost { namespace spirit { namespace traits
0216 {
0217     ///////////////////////////////////////////////////////////////////////////
0218     template <typename Subject>
0219     struct has_semantic_action<karma::duplicate_directive<Subject> >
0220       : unary_has_semantic_action<Subject> {};
0221 
0222     ///////////////////////////////////////////////////////////////////////////
0223     template <typename Subject, typename Attribute, typename Context
0224         , typename Iterator>
0225     struct handles_container<karma::duplicate_directive<Subject>, Attribute
0226         , Context, Iterator>
0227       : unary_handles_container<Subject, Attribute, Context, Iterator> {};
0228 }}}
0229 
0230 #endif