📄 multi_pass.hpp
字号:
{
// don't let the queue get larger than N
if (mp.queuedElements->size() >= N)
mp.queuedElements->pop_front();
mp.queuedElements->push_back(mp.get_input());
mp.advance_input();
}
++mp.queuePosition;
}
// no-op
void clear_queue()
{}
// called to determine whether the iterator is an eof iterator
template <typename MultiPassT>
static bool is_eof(MultiPassT const& mp)
{
return mp.queuePosition == mp.queuedElements->end() &&
mp.input_at_eof();
}
// called by operator==
bool equal_to(inner const& x) const
{
return queuePosition == x.queuePosition;
}
// called by operator<
bool less_than(inner const& x) const
{
return queuePosition < x.queuePosition;
}
}; // class inner
}; // class fixed_size_queue
///////////////////////////////////////////////////////////////////////////////
// class input_iterator
// Implementation of the InputPolicy used by multi_pass
// input_iterator encapsulates an input iterator of type InputT
///////////////////////////////////////////////////////////////////////////////
class input_iterator
{
public:
template <typename InputT>
class inner
{
typedef
typename boost::detail::iterator_traits<InputT>::value_type
result_type;
struct Data {
Data(InputT const &input_)
: input(input_), was_initialized(false)
{}
InputT input;
result_type curtok;
bool was_initialized;
};
// Needed by compilers not implementing the resolution to DR45. For
// reference, see
// http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#45.
friend struct Data;
public:
typedef result_type value_type;
typedef
typename boost::detail::iterator_traits<InputT>::difference_type
difference_type;
typedef
typename boost::detail::iterator_traits<InputT>::pointer
pointer;
typedef
typename boost::detail::iterator_traits<InputT>::reference
reference;
protected:
inner()
: data(0)
{}
inner(InputT x)
: data(new Data(x))
{}
inner(inner const& x)
: data(x.data)
{}
void destroy()
{
delete data;
data = 0;
}
bool same_input(inner const& x) const
{
return data == x.data;
}
typedef
typename boost::detail::iterator_traits<InputT>::value_type
value_t;
void swap(inner& x)
{
impl::mp_swap(data, x.data);
}
void ensure_initialized() const
{
if (data && !data->was_initialized) {
data->curtok = *data->input; // get the first token
data->was_initialized = true;
}
}
public:
reference get_input() const
{
BOOST_SPIRIT_ASSERT(NULL != data);
ensure_initialized();
return data->curtok;
}
void advance_input()
{
BOOST_SPIRIT_ASSERT(NULL != data);
data->was_initialized = false; // should get the next token
++data->input;
}
bool input_at_eof() const
{
return !data || data->input == InputT();
}
private:
Data *data;
};
};
///////////////////////////////////////////////////////////////////////////////
// class lex_input
// Implementation of the InputPolicy used by multi_pass
// lex_input gets tokens (ints) from yylex()
///////////////////////////////////////////////////////////////////////////////
class lex_input
{
public:
template <typename InputT>
class inner
{
public:
typedef int value_type;
typedef std::ptrdiff_t difference_type;
typedef int* pointer;
typedef int& reference;
protected:
inner()
: curtok(new int(0))
{}
inner(InputT x)
: curtok(new int(x))
{}
inner(inner const& x)
: curtok(x.curtok)
{}
void destroy()
{
delete curtok;
curtok = 0;
}
bool same_input(inner const& x) const
{
return curtok == x.curtok;
}
void swap(inner& x)
{
impl::mp_swap(curtok, x.curtok);
}
public:
reference get_input() const
{
return *curtok;
}
void advance_input()
{
extern int yylex();
*curtok = yylex();
}
bool input_at_eof() const
{
return *curtok == 0;
}
private:
int* curtok;
};
};
///////////////////////////////////////////////////////////////////////////////
// class functor_input
// Implementation of the InputPolicy used by multi_pass
// functor_input gets tokens from a functor
// Note: the functor must have a typedef for result_type
// It also must have a static variable of type result_type defined to
// represent eof that is called eof.
///////////////////////////////////////////////////////////////////////////////
class functor_input
{
public:
template <typename FunctorT>
class inner
{
typedef typename FunctorT::result_type result_type;
public:
typedef result_type value_type;
typedef std::ptrdiff_t difference_type;
typedef result_type* pointer;
typedef result_type& reference;
protected:
inner()
: ftor(0)
, curtok(0)
{}
inner(FunctorT const& x)
: ftor(new FunctorT(x))
, curtok(new result_type((*ftor)()))
{}
inner(inner const& x)
: ftor(x.ftor)
, curtok(x.curtok)
{}
void destroy()
{
delete ftor;
ftor = 0;
delete curtok;
curtok = 0;
}
bool same_input(inner const& x) const
{
return ftor == x.ftor;
}
void swap(inner& x)
{
impl::mp_swap(curtok, x.curtok);
impl::mp_swap(ftor, x.ftor);
}
public:
reference get_input() const
{
return *curtok;
}
void advance_input()
{
if (curtok) {
*curtok = (*ftor)();
}
}
bool input_at_eof() const
{
return !curtok || *curtok == ftor->eof;
}
FunctorT& get_functor() const
{
return *ftor;
}
private:
FunctorT* ftor;
result_type* curtok;
};
};
} // namespace multi_pass_policies
///////////////////////////////////////////////////////////////////////////////
// iterator_base_creator
///////////////////////////////////////////////////////////////////////////////
namespace iterator_ { namespace impl {
// Meta-function to generate a std::iterator<> base class for multi_pass. This
// is used mainly to improve conformance of compilers not supporting PTS
// and thus relying on inheritance to recognize an iterator.
// We are using boost::iterator<> because it offers an automatic workaround
// for broken std::iterator<> implementations.
template <typename InputPolicyT, typename InputT>
struct iterator_base_creator
{
typedef typename InputPolicyT::BOOST_NESTED_TEMPLATE inner<InputT> input_t;
typedef boost::iterator
<
std::forward_iterator_tag,
typename input_t::value_type,
typename input_t::difference_type,
typename input_t::pointer,
typename input_t::reference
> type;
};
}}
///////////////////////////////////////////////////////////////////////////////
// class template multi_pass (declaration)
///////////////////////////////////////////////////////////////////////////////
template
<
typename InputT,
typename InputPolicy = multi_pass_policies::input_iterator,
typename OwnershipPolicy = multi_pass_policies::ref_counted,
typename CheckingPolicy = multi_pass_policies::buf_id_check,
typename StoragePolicy = multi_pass_policies::std_deque
>
class multi_pass;
// The default multi_pass instantiation uses a ref-counted std_deque scheme.
///////////////////////////////////////////////////////////////////////////////
// class template multi_pass (definition)
///////////////////////////////////////////////////////////////////////////////
template
<
typename InputT,
typename InputPolicy,
typename OwnershipPolicy,
typename CheckingPolicy,
typename StoragePolicy
>
class multi_pass
: public OwnershipPolicy
, public CheckingPolicy
, public StoragePolicy::template inner<
typename InputPolicy::template inner<InputT>::value_type>
, public InputPolicy::template inner<InputT>
, public iterator_::impl::iterator_base_creator<InputPolicy, InputT>::type
{
typedef OwnershipPolicy OP;
typedef CheckingPolicy CHP;
typedef typename StoragePolicy::template inner<
typename InputPolicy::template inner<InputT>::value_type> SP;
typedef typename InputPolicy::template inner<InputT> IP;
typedef typename
iterator_::impl::iterator_base_creator<InputPolicy, InputT>::type
IB;
public:
typedef typename IB::value_type value_type;
typedef typename IB::difference_type difference_type;
typedef typename IB::reference reference;
typedef typename IB::pointer pointer;
typedef InputT iterator_type;
multi_pass();
explicit multi_pass(InputT input);
#if BOOST_WORKAROUND(__GLIBCPP__, == 20020514)
multi_pass(int);
#endif // BOOST_WORKAROUND(__GLIBCPP__, == 20020514)
~multi_pass();
multi_pass(multi_pass const&);
multi_pass& operator=(multi_pass const&);
void swap(multi_pass& x);
reference operator*() const;
pointer operator->() const;
multi_pass& operator++();
multi_pass operator++(int);
void clear_queue();
bool operator==(const multi_pass& y) const;
bool operator<(const multi_pass& y) const;
private: // helper functions
bool is_eof() const;
};
template
<
typename InputT,
typename InputPolicy,
typename OwnershipPolicy,
typename CheckingPolicy,
typename StoragePolicy
>
inline
multi_pass<InputT, InputPolicy, OwnershipPolicy, CheckingPolicy, StoragePolicy>::
multi_pass()
: OP()
, CHP()
, SP()
, IP()
{
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -