| /*============================================================================= |
| 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 |