PageRenderTime 28ms CodeModel.GetById 12ms app.highlight 12ms RepoModel.GetById 2ms app.codeStats 0ms

/Src/Dependencies/Boost/boost/spirit/home/karma/directive/duplicate.hpp

http://hadesmem.googlecode.com/
C++ Header | 229 lines | 175 code | 33 blank | 21 comment | 0 complexity | 9562fb29c332d7167d1cc6097ef89a51 MD5 | raw file
  1//  Copyright (c) 2001-2011 Hartmut Kaiser
  2//
  3//  Distributed under the Boost Software License, Version 1.0. (See accompanying
  4//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5
  6#if !defined(SPIRIT_KARMA_DUPLICATE_JUL_11_2010_0954AM)
  7#define SPIRIT_KARMA_DUPLICATE_JUL_11_2010_0954AM
  8
  9#if defined(_MSC_VER)
 10#pragma once
 11#endif
 12
 13#include <boost/spirit/home/karma/meta_compiler.hpp>
 14#include <boost/spirit/home/karma/generator.hpp>
 15#include <boost/spirit/home/karma/domain.hpp>
 16#include <boost/spirit/home/karma/detail/attributes.hpp>
 17#include <boost/spirit/home/support/unused.hpp>
 18#include <boost/spirit/home/support/info.hpp>
 19#include <boost/spirit/home/support/common_terminals.hpp>
 20#include <boost/spirit/home/support/assert_msg.hpp>
 21#include <boost/spirit/home/support/has_semantic_action.hpp>
 22#include <boost/spirit/home/support/handles_container.hpp>
 23#include <boost/fusion/include/cons.hpp>
 24#include <boost/fusion/include/vector.hpp>
 25#include <boost/fusion/include/at_c.hpp>
 26#include <boost/mpl/identity.hpp>
 27#include <boost/mpl/bool.hpp>
 28
 29namespace boost { namespace spirit
 30{
 31    ///////////////////////////////////////////////////////////////////////////
 32    // Enablers
 33    ///////////////////////////////////////////////////////////////////////////
 34    template <>
 35    struct use_directive<karma::domain, tag::duplicate> // enables duplicate
 36      : mpl::true_ {};
 37}}
 38
 39namespace boost { namespace spirit { namespace karma
 40{
 41#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
 42    using spirit::duplicate;
 43#endif
 44    using spirit::duplicate_type;
 45
 46    ///////////////////////////////////////////////////////////////////////////
 47    namespace detail
 48    {
 49        ///////////////////////////////////////////////////////////////////////
 50        template <typename T
 51          , bool IsSequence = fusion::traits::is_sequence<T>::value>
 52        struct attribute_count
 53          : fusion::result_of::size<T> 
 54        {};
 55
 56        template <>
 57        struct attribute_count<unused_type, false> 
 58          : mpl::int_<0> 
 59        {};
 60
 61        template <typename T>
 62        struct attribute_count<T, false> 
 63          : mpl::int_<1> 
 64        {};
 65
 66        ///////////////////////////////////////////////////////////////////////
 67        template <typename T
 68          , bool IsSequence = fusion::traits::is_sequence<T>::value>
 69        struct first_attribute_of_subject 
 70          : fusion::result_of::at_c<T, 0> 
 71        {};
 72
 73        template <typename T>
 74        struct first_attribute_of_subject<T, false> 
 75          : mpl::identity<T> 
 76        {};
 77
 78        template <typename T, typename Context, typename Iterator>
 79        struct first_attribute_of
 80          : first_attribute_of_subject<
 81                typename traits::attribute_of<T, Context, Iterator>::type>
 82        {};
 83
 84        ///////////////////////////////////////////////////////////////////////
 85        template <typename Attribute, typename T, int N>
 86        struct duplicate_sequence_attribute
 87        {
 88            typedef typename fusion::result_of::make_cons<
 89                reference_wrapper<T const>
 90              , typename duplicate_sequence_attribute<Attribute, T, N-1>::type
 91            >::type type;
 92
 93            static type call(T const& t)
 94            {
 95                return fusion::make_cons(cref(t)
 96                  , duplicate_sequence_attribute<Attribute, T, N-1>::call(t));
 97            }
 98        };
 99
100        template <typename Attribute, typename T>
101        struct duplicate_sequence_attribute<Attribute, T, 1> 
102        {
103            typedef typename fusion::result_of::make_cons<
104                reference_wrapper<T const> >::type type;
105
106            static type call(T const& t)
107            {
108                return fusion::make_cons(cref(t));
109            }
110        };
111
112        ///////////////////////////////////////////////////////////////////////
113        template <typename Attribute, typename T
114          , int N = attribute_count<Attribute>::value
115          , bool IsSequence = fusion::traits::is_sequence<Attribute>::value>
116        struct duplicate_attribute
117        {
118            BOOST_SPIRIT_ASSERT_MSG(N > 0, invalid_duplication_count, (Attribute));
119
120            typedef typename duplicate_sequence_attribute<Attribute, T, N>::type
121                cons_type;
122            typedef typename fusion::result_of::as_vector<cons_type>::type type;
123
124            static type call(T const& t)
125            {
126                return fusion::as_vector(
127                    duplicate_sequence_attribute<Attribute, T, N>::call(t));
128            }
129        };
130
131        template <typename Attribute, typename T>
132        struct duplicate_attribute<Attribute, T, 0, false> 
133        {
134            typedef unused_type type;
135
136            static type call(T const&)
137            {
138                return unused;
139            }
140        };
141
142        template <typename Attribute, typename T, int N>
143        struct duplicate_attribute<Attribute, T, N, false>
144        {
145            typedef Attribute const& type;
146
147            static type call(T const& t)
148            {
149                return t;
150            }
151        };
152    }
153
154    template <typename Attribute, typename T>
155    inline typename detail::duplicate_attribute<Attribute, T>::type
156    duplicate_attribute(T const& t)
157    { 
158        return detail::duplicate_attribute<Attribute, T>::call(t);
159    }
160
161    ///////////////////////////////////////////////////////////////////////////
162    // duplicate_directive duplicate its attribute for all elements of the 
163    // subject generator without generating anything itself
164    ///////////////////////////////////////////////////////////////////////////
165    template <typename Subject>
166    struct duplicate_directive : unary_generator<duplicate_directive<Subject> >
167    {
168        typedef Subject subject_type;
169        typedef typename subject_type::properties properties;
170
171        duplicate_directive(Subject const& subject)
172          : subject(subject) {}
173
174        template <typename Context, typename Iterator = unused_type>
175        struct attribute
176          : detail::first_attribute_of<Subject, Context, Iterator>
177        {};
178
179        template <typename OutputIterator, typename Context, typename Delimiter
180          , typename Attribute>
181        bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
182          , Attribute const& attr) const
183        {
184            typedef typename traits::attribute_of<Subject, Context>::type 
185                subject_attr_type;
186            return subject.generate(sink, ctx, d
187              , duplicate_attribute<subject_attr_type>(attr));
188        }
189
190        template <typename Context>
191        info what(Context& context) const
192        {
193            return info("duplicate", subject.what(context));
194        }
195
196        Subject subject;
197    };
198
199    ///////////////////////////////////////////////////////////////////////////
200    // Generator generators: make_xxx function (objects)
201    ///////////////////////////////////////////////////////////////////////////
202    template <typename Subject, typename Modifiers>
203    struct make_directive<tag::duplicate, Subject, Modifiers>
204    {
205        typedef duplicate_directive<Subject> result_type;
206        result_type operator()(unused_type, Subject const& subject
207          , unused_type) const
208        {
209            return result_type(subject);
210        }
211    };
212}}}
213
214namespace boost { namespace spirit { namespace traits
215{
216    ///////////////////////////////////////////////////////////////////////////
217    template <typename Subject>
218    struct has_semantic_action<karma::duplicate_directive<Subject> >
219      : unary_has_semantic_action<Subject> {};
220
221    ///////////////////////////////////////////////////////////////////////////
222    template <typename Subject, typename Attribute, typename Context
223        , typename Iterator>
224    struct handles_container<karma::duplicate_directive<Subject>, Attribute
225        , Context, Iterator>
226      : unary_handles_container<Subject, Attribute, Context, Iterator> {};
227}}}
228
229#endif