1 //  Copyright (c) 2001-2011 Hartmut Kaiser
2 //  Copyright (c) 2001-2011 Joel de Guzman
3 //
4 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
5 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 
7 #if !defined(BOOST_SPIRIT_GENERATOR_JANUARY_13_2009_1002AM)
8 #define BOOST_SPIRIT_GENERATOR_JANUARY_13_2009_1002AM
9 
10 #if defined(_MSC_VER)
11 #pragma once
12 #endif
13 
14 #include <boost/mpl/has_xxx.hpp>
15 #include <boost/mpl/int.hpp>
16 #include <boost/spirit/home/karma/domain.hpp>
17 
18 namespace boost { namespace spirit { namespace karma
19 {
20     struct generator_properties
21     {
22         enum enum_type {
23             no_properties = 0,
24             buffering = 0x01,        // generator requires buffering
25             counting = 0x02,         // generator requires counting
26             tracking = 0x04,         // generator requires position tracking
27             disabling = 0x08,        // generator requires disabling of output
28 
29             countingbuffer = 0x03,   // buffering | counting
30             all_properties = 0x0f    // buffering | counting | tracking | disabling
31         };
32     };
33 
34     template <typename Derived>
35     struct generator
36     {
37         struct generator_id;
38         typedef mpl::int_<generator_properties::no_properties> properties;
39         typedef Derived derived_type;
40         typedef karma::domain domain;
41 
42         // Requirement: g.generate(o, context, delimiter, attr) -> bool
43         //
44         //  g:          a generator
45         //  o:          output iterator
46         //  context:    enclosing rule context (can be unused_type)
47         //  delimit:    delimiter (can be unused_type)
48         //  attr:       attribute (can be unused_type)
49 
50         // Requirement: g.what(context) -> info
51         //
52         //  g:          a generator
53         //  context:    enclosing rule context (can be unused_type)
54 
55         // Requirement: G::template attribute<Ctx, Iter>::type
56         //
57         //  G:          a generator type
58         //  Ctx:        A context type (can be unused_type)
59         //  Iter:       An iterator type (always unused_type)
60 
derivedboost::spirit::karma::generator61         Derived const& derived() const
62         {
63             return *static_cast<Derived const*>(this);
64         }
65     };
66 
67     template <typename Derived>
68     struct primitive_generator : generator<Derived>
69     {
70         struct primitive_generator_id;
71     };
72 
73     template <typename Derived>
74     struct nary_generator : generator<Derived>
75     {
76         struct nary_generator_id;
77 
78         // Requirement: g.elements -> fusion sequence
79         //
80         // g:   a composite generator
81 
82         // Requirement: G::elements_type -> fusion sequence
83         //
84         // G:   a composite generator type
85     };
86 
87     template <typename Derived>
88     struct unary_generator : generator<Derived>
89     {
90         struct unary_generator_id;
91 
92         // Requirement: g.subject -> subject generator
93         //
94         // g:   a unary generator
95 
96         // Requirement: G::subject_type -> subject generator type
97         //
98         // G:   a unary generator type
99     };
100 
101     template <typename Derived>
102     struct binary_generator : generator<Derived>
103     {
104         struct binary_generator_id;
105 
106         // Requirement: g.left -> left generator
107         //
108         // g:   a binary generator
109 
110         // Requirement: G::left_type -> left generator type
111         //
112         // G:   a binary generator type
113 
114         // Requirement: g.right -> right generator
115         //
116         // g:   a binary generator
117 
118         // Requirement: G::right_type -> right generator type
119         //
120         // G:   a binary generator type
121     };
122 
123 }}}
124 
125 namespace boost { namespace spirit { namespace traits // classification
126 {
127     namespace detail
128     {
129         // generator tags
130         BOOST_MPL_HAS_XXX_TRAIT_DEF(generator_id)
131         BOOST_MPL_HAS_XXX_TRAIT_DEF(primitive_generator_id)
132         BOOST_MPL_HAS_XXX_TRAIT_DEF(nary_generator_id)
133         BOOST_MPL_HAS_XXX_TRAIT_DEF(unary_generator_id)
134         BOOST_MPL_HAS_XXX_TRAIT_DEF(binary_generator_id)
135     }
136 
137     // check for generator tags
138     template <typename T>
139     struct is_generator : detail::has_generator_id<T> {};
140 
141     template <typename T>
142     struct is_primitive_generator : detail::has_primitive_generator_id<T> {};
143 
144     template <typename T>
145     struct is_nary_generator : detail::has_nary_generator_id<T> {};
146 
147     template <typename T>
148     struct is_unary_generator : detail::has_unary_generator_id<T> {};
149 
150     template <typename T>
151     struct is_binary_generator : detail::has_binary_generator_id<T> {};
152 
153     // check for generator properties
154     template <typename T>
155     struct properties_of : T::properties {};
156 
157 }}}
158 
159 #endif
160