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_SUPPORT_NO_CASE_SEPT_24_2014_1125PM)
8 #define BOOST_SPIRIT_X3_SUPPORT_NO_CASE_SEPT_24_2014_1125PM
9 
10 #include <boost/spirit/home/x3/support/unused.hpp>
11 #include <boost/spirit/home/x3/support/context.hpp>
12 #include <boost/spirit/home/x3/char/char_class_tags.hpp>
13 
14 namespace boost { namespace spirit { namespace x3
15 {
16     struct no_case_tag {};
17 
18     template <typename Encoding>
19     struct case_compare
20     {
21         template < template <typename> class basic_charset>
22         typename Encoding::char_type
in_setboost::spirit::x3::case_compare23         in_set( typename Encoding::char_type const ch
24               , basic_charset<typename Encoding::char_type> const &set)
25         {
26             return set.test(ch);
27         }
28 
operator ()boost::spirit::x3::case_compare29         int32_t operator()(
30               typename Encoding::char_type const lc
31             , typename Encoding::char_type const rc) const
32         {
33             return lc - rc;
34         }
35 
36 
37         template <typename CharClassTag>
get_char_class_tagboost::spirit::x3::case_compare38         CharClassTag get_char_class_tag(CharClassTag tag) const
39         {
40             return tag;
41         }
42     };
43 
44     template <typename Encoding>
45     struct no_case_compare
46     {
47         template < template <typename> class basic_charset>
48         typename Encoding::char_type
in_setboost::spirit::x3::no_case_compare49         in_set( typename Encoding::char_type const ch
50               , basic_charset<typename Encoding::char_type> const &set)
51         {
52             return set.test(ch)
53                 || set.test(Encoding::islower(ch) ? Encoding::toupper(ch) : Encoding::tolower(ch));
54         }
55 
operator ()boost::spirit::x3::no_case_compare56         int32_t operator()(
57               typename Encoding::char_type const lc
58             , typename Encoding::char_type const rc) const
59         {
60             return Encoding::islower(rc) ? Encoding::tolower(lc) - rc : Encoding::toupper(lc) - rc;
61         }
62 
63         template <typename CharClassTag>
get_char_class_tagboost::spirit::x3::no_case_compare64         CharClassTag get_char_class_tag(CharClassTag tag) const
65         {
66             return tag;
67         }
68 
get_char_class_tagboost::spirit::x3::no_case_compare69         alpha_tag get_char_class_tag(lower_tag ) const
70         {
71             return {};
72         }
73 
get_char_class_tagboost::spirit::x3::no_case_compare74         alpha_tag get_char_class_tag(upper_tag ) const
75         {
76             return {};
77         }
78 
79     };
80 
81     template <typename Encoding>
get_case_compare_impl(unused_type const &)82     case_compare<Encoding> get_case_compare_impl(unused_type const&)
83     {
84         return {};
85     }
86 
87     template <typename Encoding>
get_case_compare_impl(no_case_tag const &)88     no_case_compare<Encoding> get_case_compare_impl(no_case_tag const&)
89     {
90         return {};
91     }
92 
93     template <typename Encoding, typename Context>
get_case_compare(Context const & context)94     inline decltype(auto) get_case_compare(Context const& context)
95     {
96         return get_case_compare_impl<Encoding>(x3::get<no_case_tag>(context));
97     }
98     auto const no_case_compare_ = no_case_tag{};
99 
100 }}}
101 
102 #endif
103