1 ///////////////////////////////////////////////////////////////////////////////
2 // assert_word_matcher.hpp
3 //
4 //  Copyright 2008 Eric Niebler. Distributed under the Boost
5 //  Software License, Version 1.0. (See accompanying file
6 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 
8 #ifndef BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_ASSERT_WORD_MATCHER_HPP_EAN_10_04_2005
9 #define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_ASSERT_WORD_MATCHER_HPP_EAN_10_04_2005
10 
11 // MS compatible compilers support #pragma once
12 #if defined(_MSC_VER)
13 # pragma once
14 #endif
15 
16 #include <boost/assert.hpp>
17 #include <boost/xpressive/detail/detail_fwd.hpp>
18 #include <boost/xpressive/detail/core/quant_style.hpp>
19 #include <boost/xpressive/detail/utility/ignore_unused.hpp>
20 #include <boost/xpressive/detail/core/state.hpp>
21 
22 namespace boost { namespace xpressive { namespace detail
23 {
24 
25     ///////////////////////////////////////////////////////////////////////////////
26     // word_boundary
27     //
28     template<typename IsBoundary>
29     struct word_boundary
30     {
31         template<typename BidiIter>
evalboost::xpressive::detail::word_boundary32         static bool eval(bool prevword, bool thisword, match_state<BidiIter> &state)
33         {
34             if((state.flags_.match_not_bow_ && state.bos()) || (state.flags_.match_not_eow_ && state.eos()))
35             {
36                 return !IsBoundary::value;
37             }
38 
39             return IsBoundary::value == (prevword != thisword);
40         }
41     };
42 
43     ///////////////////////////////////////////////////////////////////////////////
44     // word_begin
45     //
46     struct word_begin
47     {
48         template<typename BidiIter>
evalboost::xpressive::detail::word_begin49         static bool eval(bool prevword, bool thisword, match_state<BidiIter> &state)
50         {
51             if(state.flags_.match_not_bow_ && state.bos())
52             {
53                 return false;
54             }
55 
56             return !prevword && thisword;
57         }
58     };
59 
60     ///////////////////////////////////////////////////////////////////////////////
61     // word_end
62     //
63     struct word_end
64     {
65         template<typename BidiIter>
evalboost::xpressive::detail::word_end66         static bool eval(bool prevword, bool thisword, match_state<BidiIter> &state)
67         {
68             if(state.flags_.match_not_eow_ && state.eos())
69             {
70                 return false;
71             }
72 
73             return prevword && !thisword;
74         }
75     };
76 
77     ///////////////////////////////////////////////////////////////////////////////
78     // assert_word_matcher
79     //
80     template<typename Cond, typename Traits>
81     struct assert_word_matcher
82       : quant_style_assertion
83     {
84         typedef typename Traits::char_type char_type;
85         typedef typename Traits::char_class_type char_class_type;
86 
assert_word_matcherboost::xpressive::detail::assert_word_matcher87         assert_word_matcher(Traits const &tr)
88           : word_(lookup_classname(tr, "w"))
89         {
90             BOOST_ASSERT(0 != this->word_);
91         }
92 
assert_word_matcherboost::xpressive::detail::assert_word_matcher93         assert_word_matcher(char_class_type word)
94           : word_(word)
95         {}
96 
is_wordboost::xpressive::detail::assert_word_matcher97         bool is_word(Traits const &tr, char_type ch) const
98         {
99             detail::ignore_unused(tr);
100             return tr.isctype(tr.translate(ch), this->word_);
101         }
102 
103         template<typename BidiIter, typename Next>
matchboost::xpressive::detail::assert_word_matcher104         bool match(match_state<BidiIter> &state, Next const &next) const
105         {
106             BidiIter cur = state.cur_;
107             bool const thisword = !state.eos() && this->is_word(traits_cast<Traits>(state), *cur);
108             bool const prevword = (!state.bos() || state.flags_.match_prev_avail_)
109                 && this->is_word(traits_cast<Traits>(state), *--cur);
110 
111             return Cond::eval(prevword, thisword, state) && next.match(state);
112         }
113 
wordboost::xpressive::detail::assert_word_matcher114         char_class_type word() const
115         {
116             return this->word_;
117         }
118 
119     private:
120         char_class_type word_;
121     };
122 
123 }}}
124 
125 #endif
126