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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
/*=============================================================================
    Copyright (c) 2002 Juan Carlos Arevalo-Baeza
    Copyright (c) 2002-2006 Hartmut Kaiser
    Copyright (c) 2003 Giovanni Bajo
    http://spirit.sourceforge.net/
 
    Use, modification and distribution is subject to 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)
=============================================================================*/
#ifndef BOOST_SPIRIT_CLASSIC_ITERATOR_IMPL_POSITION_ITERATOR_IPP
#define BOOST_SPIRIT_CLASSIC_ITERATOR_IMPL_POSITION_ITERATOR_IPP
 
#include <boost/config.hpp>
#include <boost/iterator_adaptors.hpp>
#include <boost/type_traits/add_const.hpp>
#include <boost/mpl/if.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/spirit/home/classic/core/nil.hpp>  // for nil_t
#include <iterator> // for std::iterator_traits
 
namespace boost { namespace spirit {
 
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
 
///////////////////////////////////////////////////////////////////////////////
//
//  position_policy<file_position_without_column>
//
//  Specialization to handle file_position_without_column. Only take care of
//  newlines since no column tracking is needed.
//
///////////////////////////////////////////////////////////////////////////////
template <typename String>
class position_policy<file_position_without_column_base<String> > {
 
public:
    void next_line(file_position_without_column_base<String>& pos)
    {
        ++pos.line;
    }
 
    void set_tab_chars(unsigned int /*chars*/){}
    void next_char(file_position_without_column_base<String>& /*pos*/)    {}
    void tabulation(file_position_without_column_base<String>& /*pos*/)   {}
};
 
///////////////////////////////////////////////////////////////////////////////
//
//  position_policy<file_position>
//
//  Specialization to handle file_position. Track characters and tabulation
//  to compute the current column correctly.
//
//  Default tab size is 4. You can change this with the set_tabchars member
//  of position_iterator.
//
///////////////////////////////////////////////////////////////////////////////
template <typename String>
class position_policy<file_position_base<String> > {
 
public:
    position_policy()
        : m_CharsPerTab(4)
    {}
 
    void next_line(file_position_base<String>& pos)
    {
        ++pos.line;
        pos.column = 1;
    }
 
    void set_tab_chars(unsigned int chars)
    {
        m_CharsPerTab = chars;
    }
 
    void next_char(file_position_base<String>& pos)
    {
        ++pos.column;
    }
 
    void tabulation(file_position_base<String>& pos)
    {
        pos.column += m_CharsPerTab - (pos.column - 1) % m_CharsPerTab;
    }
 
private:
    unsigned int m_CharsPerTab;
};
 
/* namespace boost::spirit { */ namespace iterator_ { namespace impl {
 
template <typename T>
struct make_const : boost::add_const<T>
{};
 
template <typename T>
struct make_const<T&>
{
    typedef typename boost::add_const<T>::type& type;
};
 
///////////////////////////////////////////////////////////////////////////////
//
//  position_iterator_base_generator
//
//  Metafunction to generate the iterator type using boost::iterator_adaptors,
//  hiding all the metaprogramming thunking code in it. It is used
//  mainly to keep the public interface (position_iterator) cleanear.
//
///////////////////////////////////////////////////////////////////////////////
template <typename MainIterT, typename ForwardIterT, typename PositionT>
struct position_iterator_base_generator
{
private:
    typedef std::iterator_traits<ForwardIterT> traits;
    typedef typename traits::value_type value_type;
    typedef typename traits::iterator_category iter_category_t;
    typedef typename traits::reference reference;
 
    // Position iterator is always a non-mutable iterator
    typedef typename boost::add_const<value_type>::type const_value_type;
 
public:
    // Check if the MainIterT is nil. If it's nil, it means that the actual
    //  self type is position_iterator. Otherwise, it's a real type we
    //  must use
    typedef typename boost::mpl::if_<
        typename boost::is_same<MainIterT, nil_t>::type,
        position_iterator<ForwardIterT, PositionT, nil_t>,
        MainIterT
    >::type main_iter_t;
 
    typedef boost::iterator_adaptor<
        main_iter_t,
        ForwardIterT,
        const_value_type,
        boost::forward_traversal_tag,
        typename make_const<reference>::type
    > type;
};
 
}}
 
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
 
}} /* namespace boost::spirit::iterator_::impl */
 
#endif