1 /*=============================================================================
2     Copyright (c) 2001-2014 Joel de Guzman
3 
4     Distributed under the Boost Software License, Version 1.0. (See accompanying
5     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 ==============================================================================*/
7 #if !defined(BOOST_SPIRIT_X3_NO_CASE_STRING_PARSE_APR_18_2014_1125PM)
8 #define BOOST_SPIRIT_X3_NO_CASE_STRING_PARSE_APR_18_2014_1125PM
9 
10 #include <boost/spirit/home/x3/char/char.hpp>
11 #include <boost/spirit/home/x3/support/traits/move_to.hpp>
12 
13 namespace boost { namespace spirit { namespace x3 { namespace detail
14 {
15     template <typename Char, typename Encoding>
16     struct no_case_string
17     {
18         typedef std::basic_string< Char >  string_type;
19         typedef typename string_type::const_iterator const_iterator;
20 
no_case_stringboost::spirit::x3::detail::no_case_string21         no_case_string(char_type const* str)
22           : lower(str)
23           , upper(str)
24         {
25             typename string_type::iterator loi = lower.begin();
26             typename string_type::iterator upi = upper.begin();
27 
28             typedef typename Encoding::char_type encoded_char_type;
29             Encoding encoding;
30             for (; loi != lower.end(); ++loi, ++upi)
31             {
32                 *loi = static_cast<char_type>(encoding.tolower(encoded_char_type(*loi)));
33                 *upi = static_cast<char_type>(encoding.toupper(encoded_char_type(*upi)));
34             }
35         }
36         string_type lower;
37         string_type upper;
38 
39     };
40 
41     template <typename String, typename Iterator, typename Attribute>
no_case_string_parse(String const & str,Iterator & first,Iterator const & last,Attribute & attr)42     inline bool no_case_string_parse(
43         String const& str
44       , Iterator& first, Iterator const& last, Attribute& attr)
45     {
46         typename String::const_iterator uc_i = str.upper.begin();
47         typename String::const_iterator uc_last = str.upper.end();
48         typename String::const_iterator lc_i = str.lower.begin();
49         Iterator i = first;
50 
51         for (; uc_i != uc_last; ++uc_i, ++lc_i, ++i)
52             if (i == last || ((*uc_i != *i) && (*lc_i != *i)))
53                 return false;
54         x3::traits::move_to(first, i, attr);
55         first = i;
56         return true;
57     }
58 }}}}
59 
60 #endif
61