/*============================================================================= | |
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 POSITION_ITERATOR_IPP | |
#define 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 <boost/detail/iterator.hpp> // for boost::detail::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 { | |
/////////////////////////////////////////////////////////////////////////////// | |
// | |
// 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 boost::detail::iterator_traits<ForwardIterT> traits; | |
typedef typename traits::value_type value_type; | |
typedef typename traits::iterator_category iter_category_t; | |
// 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 | |
> type; | |
}; | |
}} | |
BOOST_SPIRIT_CLASSIC_NAMESPACE_END | |
}} /* namespace boost::spirit::iterator_::impl */ | |
#endif |