zhangmeng
2021-07-02 056f71f24cefaf88f2a93714c6678c03ed5f1e0e
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_PHOENIX_ATTRIBUTES_OCT_01_2009_1128AM)
#define BOOST_SPIRIT_KARMA_PHOENIX_ATTRIBUTES_OCT_01_2009_1128AM
 
#if defined(_MSC_VER)
#pragma once
#endif
 
#include <boost/spirit/include/version.hpp>
 
// we support Phoenix attributes only starting with V2.2
#if SPIRIT_VERSION >= 0x2020
 
#include <boost/spirit/home/karma/detail/attributes.hpp>
#include <boost/spirit/home/karma/detail/indirect_iterator.hpp>
#include <boost/spirit/home/support/container.hpp>
 
#include <boost/utility/result_of.hpp>
 
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace phoenix
{
    template <typename Expr>
    struct actor;
}}
 
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace traits
{
    ///////////////////////////////////////////////////////////////////////////
    // Provide customization points allowing the use of phoenix expressions as 
    // generator functions in the context of generators expecting a container 
    // attribute (Kleene, plus, list, repeat, etc.)
    ///////////////////////////////////////////////////////////////////////////
    template <typename Eval>
    struct is_container<phoenix::actor<Eval> const>
      : is_container<typename boost::result_of<phoenix::actor<Eval>()>::type>
    {};
 
    template <typename Eval>
    struct container_iterator<phoenix::actor<Eval> const>
    {
        typedef phoenix::actor<Eval> const& type;
    };
 
    template <typename Eval>
    struct begin_container<phoenix::actor<Eval> const>
    {
        typedef phoenix::actor<Eval> const& type;
        static type call(phoenix::actor<Eval> const& f)
        {
            return f;
        }
    };
 
    template <typename Eval>
    struct end_container<phoenix::actor<Eval> const>
    {
        typedef phoenix::actor<Eval> const& type;
        static type call(phoenix::actor<Eval> const& f)
        {
            return f;
        }
    };
 
    template <typename Eval>
    struct deref_iterator<phoenix::actor<Eval> const>
    {
        typedef typename boost::result_of<phoenix::actor<Eval>()>::type type;
        static type call(phoenix::actor<Eval> const& f)
        {
            return f();
        }
    };
 
    template <typename Eval>
    struct next_iterator<phoenix::actor<Eval> const>
    {
        typedef phoenix::actor<Eval> const& type;
        static type call(phoenix::actor<Eval> const& f)
        {
            return f;
        }
    };
 
    template <typename Eval>
    struct compare_iterators<phoenix::actor<Eval> const>
    {
        static bool 
        call(phoenix::actor<Eval> const&, phoenix::actor<Eval> const&)
        {
            return false;
        }
    };
 
    template <typename Eval>
    struct container_value<phoenix::actor<Eval> >
    {
        typedef phoenix::actor<Eval> const& type;
    };
 
    template <typename Eval>
    struct make_indirect_iterator<phoenix::actor<Eval> const>
    {
        typedef phoenix::actor<Eval> const& type;
    };
 
    ///////////////////////////////////////////////////////////////////////////
    // Handle Phoenix actors as attributes, just invoke the function object
    // and deal with the result as the attribute.
    ///////////////////////////////////////////////////////////////////////////
    template <typename Eval, typename Exposed>
    struct extract_from_attribute<phoenix::actor<Eval>, Exposed>
    {
        typedef typename boost::result_of<phoenix::actor<Eval>()>::type type;
 
        template <typename Context>
        static type call(phoenix::actor<Eval> const& f, Context& context)
        {
            return f(unused, context);
        }
    };
}}}
 
#endif
#endif