liuxiaolong
2021-07-20 58d904a328c0d849769b483e901a0be9426b8209
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
//  Copyright (c) 2001-2011 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_DETAIL_GENERATE_FEB_20_2007_0959AM)
#define BOOST_SPIRIT_KARMA_DETAIL_GENERATE_FEB_20_2007_0959AM
 
#if defined(_MSC_VER)
#pragma once
#endif
 
#include <boost/spirit/home/karma/meta_compiler.hpp>
#include <boost/spirit/home/karma/delimit_out.hpp>
#include <boost/spirit/home/karma/delimit_flag.hpp>
#include <boost/spirit/home/karma/detail/output_iterator.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/bool.hpp>
 
namespace boost { namespace spirit { namespace karma { namespace detail
{
    ///////////////////////////////////////////////////////////////////////////
    template <typename Expr, typename Enable = void>
    struct generate_impl
    {
        // Report invalid expression error as early as possible.
        // If you got an error_invalid_expression error message here,
        // then the expression (Expr) is not a valid spirit karma expression.
        // Did you intend to use the auto_ facilities while forgetting to 
        // #include <boost/spirit/include/karma_auto.hpp>?
        BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Expr);
    };
 
    template <typename Expr>
    struct generate_impl<Expr
      , typename enable_if<traits::matches<karma::domain, Expr> >::type>
    {
        template <typename OutputIterator>
        static bool call(
            OutputIterator& target_sink
          , Expr const& expr)
        {
            typedef traits::properties_of<
                typename result_of::compile<karma::domain, Expr>::type
            > properties;
 
            // wrap user supplied iterator into our own output iterator
            output_iterator<OutputIterator
              , mpl::int_<properties::value> > sink(target_sink);
            return compile<karma::domain>(expr).
                generate(sink, unused, unused, unused);
        }
 
        template <typename OutputIterator, typename Properties>
        static bool call(
            detail::output_iterator<OutputIterator, Properties>& sink
          , Expr const& expr)
        {
            return compile<karma::domain>(expr).
                generate(sink, unused, unused, unused);
        }
    };
 
    ///////////////////////////////////////////////////////////////////////////
    template <typename Expr, typename Enable = void>
    struct generate_delimited_impl
    {
        // Report invalid expression error as early as possible.
        // If you got an error_invalid_expression error message here,
        // then the expression (Expr) is not a valid spirit karma expression.
        // Did you intend to use the auto_ facilities while forgetting to 
        // #include <boost/spirit/include/karma_auto.hpp>?
        BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Expr);
    };
 
    template <typename Expr>
    struct generate_delimited_impl<Expr
      , typename enable_if<traits::matches<karma::domain, Expr> >::type>
    {
        template <typename OutputIterator, typename Delimiter>
        static bool call(
            OutputIterator& target_sink
          , Expr const& expr
          , Delimiter const& delimiter
          , BOOST_SCOPED_ENUM(delimit_flag) pre_delimit)
        {
            typedef traits::properties_of<
                typename result_of::compile<karma::domain, Expr>::type
            > properties;
            typedef traits::properties_of<
                typename result_of::compile<karma::domain, Delimiter>::type
            > delimiter_properties;
 
            // wrap user supplied iterator into our own output iterator
            detail::output_iterator<OutputIterator
              , mpl::int_<properties::value | delimiter_properties::value>
            > sink(target_sink);
            return call(sink, expr, delimiter, pre_delimit);
        }
 
        template <typename OutputIterator, typename Properties
          , typename Delimiter>
        static bool call(
            detail::output_iterator<OutputIterator, Properties>& sink
          , Expr const& expr
          , Delimiter const& delimiter
          , BOOST_SCOPED_ENUM(delimit_flag) pre_delimit)
        {
            // Report invalid expression error as early as possible.
            // If you got an error_invalid_expression error message here,
            // then the delimiter is not a valid spirit karma expression.
            BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Delimiter);
 
            typename result_of::compile<karma::domain, Delimiter>::type const 
                delimiter_ = compile<karma::domain>(delimiter);
 
            if (pre_delimit == delimit_flag::predelimit &&
                !karma::delimit_out(sink, delimiter_))
            {
                return false;
            }
            return compile<karma::domain>(expr).
                generate(sink, unused, delimiter_, unused);
        }
    };
 
}}}}
 
#endif