1bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant//===----------------------------------------------------------------------===//
2bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant//
3f5256e16dfc425c1d466f6308d4026d529ce9e0bHoward Hinnant//                     The LLVM Compiler Infrastructure
4bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant//
5b64f8b07c104c6cc986570ac8ee0ed16a9f23976Howard Hinnant// This file is dual licensed under the MIT and the University of Illinois Open
6b64f8b07c104c6cc986570ac8ee0ed16a9f23976Howard Hinnant// Source Licenses. See LICENSE.TXT for details.
7bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant//
8bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant//===----------------------------------------------------------------------===//
9bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
10bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// <locale>
11bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
12bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// Not a portable test
13bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
14bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// __scan_keyword
15bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// Scans [__b, __e) until a match is found in the basic_strings range
16bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant//  [__kb, __ke) or until it can be shown that there is no match in [__kb, __ke).
17bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant//  __b will be incremented (visibly), consuming CharT until a match is found
18bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant//  or proved to not exist.  A keyword may be "", in which will match anything.
19bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant//  If one keyword is a prefix of another, and the next CharT in the input
20bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant//  might match another keyword, the algorithm will attempt to find the longest
21bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant//  matching keyword.  If the longer matching keyword ends up not matching, then
22bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant//  no keyword match is found.  If no keyword match is found, __ke is returned.
23bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant//  Else an iterator pointing to the matching keyword is found.  If more than
24bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant//  one keyword matches, an iterator to the first matching keyword is returned.
25bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant//  If on exit __b == __e, eofbit is set in __err.  If __case_senstive is false,
26bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant//  __ct is used to force to lower case before comparing characters.
27bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant//  Examples:
28bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant//  Keywords:  "a", "abb"
29bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant//  If the input is "a", the first keyword matches and eofbit is set.
30bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant//  If the input is "abc", no match is found and "ab" are consumed.
31bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant//
32bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// template <class _InputIterator, class _ForwardIterator, class _Ctype>
33bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// _ForwardIterator
34bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// __scan_keyword(_InputIterator& __b, _InputIterator __e,
35bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant//                _ForwardIterator __kb, _ForwardIterator __ke,
36bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant//                const _Ctype& __ct, ios_base::iostate& __err,
37bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant//                bool __case_sensitive = true);
38bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
39bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#include <locale>
40bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#include <cassert>
41bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
42bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantint main()
43bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{
44bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    const std::ctype<char>& ct = std::use_facet<std::ctype<char> >(std::locale::classic());
45bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    std::ios_base::iostate err = std::ios_base::goodbit;
46bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    {
47bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        const char input[] = "a";
48bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        const char* in = input;
49bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        std::string keys[] = {"a", "abb"};
50bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        err = std::ios_base::goodbit;
51bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        std::string* k = std::__scan_keyword(in, input+sizeof(input)-1,
52bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant                                             keys, keys+sizeof(keys)/sizeof(keys[0]),
53bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant                                             ct, err);
54bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        assert(k - keys == 0);
55bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        assert(in == input+1);
56bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        assert(err == std::ios_base::eofbit);
57bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    }
58bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    {
59bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        const char input[] = "abc";
60bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        const char* in = input;
61bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        std::string keys[] = {"a", "abb"};
62bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        err = std::ios_base::goodbit;
63bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        std::string* k = std::__scan_keyword(in, input+sizeof(input)-1,
64bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant                                             keys, keys+sizeof(keys)/sizeof(keys[0]),
65bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant                                             ct, err);
66bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        assert(k - keys == 2);
67bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        assert(in == input+2);
68bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        assert(err == std::ios_base::failbit);
69bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    }
70bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    {
71bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        const char input[] = "abb";
72bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        const char* in = input;
73bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        std::string keys[] = {"a", "abb"};
74bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        err = std::ios_base::goodbit;
75bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        std::string* k = std::__scan_keyword(in, input+sizeof(input)-1,
76bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant                                             keys, keys+sizeof(keys)/sizeof(keys[0]),
77bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant                                             ct, err);
78bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        assert(k - keys == 1);
79bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        assert(in == input+3);
80bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        assert(err == std::ios_base::eofbit);
81bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    }
82bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    {
83bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        const char input[] = "Tue ";
84bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        const char* in = input;
85bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        std::string keys[] = {"Mon", "Monday", "Tue", "Tuesday"};
86bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        err = std::ios_base::goodbit;
87bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        std::string* k = std::__scan_keyword(in, input+sizeof(input)-1,
88bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant                                             keys, keys+sizeof(keys)/sizeof(keys[0]),
89bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant                                             ct, err);
90bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        assert(k - keys == 2);
91bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        assert(in == input+3);
92bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        assert(err == std::ios_base::goodbit);
93bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    }
94bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    {
95bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        const char input[] = "tue ";
96bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        const char* in = input;
97bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        std::string keys[] = {"Mon", "Monday", "Tue", "Tuesday"};
98bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        err = std::ios_base::goodbit;
99bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        std::string* k = std::__scan_keyword(in, input+sizeof(input)-1,
100bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant                                             keys, keys+sizeof(keys)/sizeof(keys[0]),
101bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant                                             ct, err);
102bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        assert(k - keys == 4);
103bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        assert(in == input+0);
104bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        assert(err == std::ios_base::failbit);
105bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    }
106bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    {
107bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        const char input[] = "tue ";
108bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        const char* in = input;
109bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        std::string keys[] = {"Mon", "Monday", "Tue", "Tuesday"};
110bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        err = std::ios_base::goodbit;
111bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        std::string* k = std::__scan_keyword(in, input+sizeof(input)-1,
112bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant                                             keys, keys+sizeof(keys)/sizeof(keys[0]),
113bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant                                             ct, err, false);
114bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        assert(k - keys == 2);
115bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        assert(in == input+3);
116bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        assert(err == std::ios_base::goodbit);
117bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    }
118bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant}
119