| 1 | // Boost string_algo library iterator_test.cpp file ---------------------------// |
| 2 | |
| 3 | // Copyright Pavol Droba 2002-2003. Use, modification and |
| 4 | // distribution is subject to the Boost Software License, Version |
| 5 | // 1.0. (See accompanying file LICENSE_1_0.txt or copy at |
| 6 | // http://www.boost.org/LICENSE_1_0.txt) |
| 7 | |
| 8 | // See http://www.boost.org for updates, documentation, and revision history. |
| 9 | |
| 10 | #include <boost/algorithm/string/config.hpp> |
| 11 | |
| 12 | #include <boost/algorithm/string/split.hpp> |
| 13 | #include <boost/algorithm/string/classification.hpp> |
| 14 | // equals predicate is used for result comparison |
| 15 | #include <boost/algorithm/string/predicate.hpp> |
| 16 | |
| 17 | // Include unit test framework |
| 18 | #define BOOST_TEST_MAIN |
| 19 | #include <boost/test/unit_test.hpp> |
| 20 | |
| 21 | #include <string> |
| 22 | #include <vector> |
| 23 | #include <list> |
| 24 | #include <iostream> |
| 25 | |
| 26 | #include <boost/test/test_tools.hpp> |
| 27 | |
| 28 | |
| 29 | using namespace std; |
| 30 | using namespace boost; |
| 31 | |
| 32 | template< typename T1, typename T2 > |
| 33 | void deep_compare( const T1& X, const T2& Y ) |
| 34 | { |
| 35 | BOOST_REQUIRE( X.size() == Y.size() ); |
| 36 | for( unsigned int nIndex=0; nIndex<X.size(); ++nIndex ) |
| 37 | { |
| 38 | BOOST_CHECK( equals( X[nIndex], Y[nIndex] ) ); |
| 39 | } |
| 40 | } |
| 41 | |
| 42 | void iterator_test() |
| 43 | { |
| 44 | string str1("xx-abc--xx-abb" ); |
| 45 | string str2("Xx-abc--xX-abb-xx" ); |
| 46 | string str3("xx" ); |
| 47 | string strempty("" ); |
| 48 | const char* pch1="xx-abc--xx-abb" ; |
| 49 | vector<string> tokens; |
| 50 | vector< vector<int> > vtokens; |
| 51 | |
| 52 | // find_all tests |
| 53 | find_all( |
| 54 | Result&: tokens, |
| 55 | Input&: pch1, |
| 56 | Search: "xx" ); |
| 57 | |
| 58 | BOOST_REQUIRE( tokens.size()==2 ); |
| 59 | BOOST_CHECK( tokens[0]==string("xx" ) ); |
| 60 | BOOST_CHECK( tokens[1]==string("xx" ) ); |
| 61 | |
| 62 | ifind_all( |
| 63 | Result&: tokens, |
| 64 | Input&: str2, |
| 65 | Search: "xx" ); |
| 66 | |
| 67 | BOOST_REQUIRE( tokens.size()==3 ); |
| 68 | BOOST_CHECK( tokens[0]==string("Xx" ) ); |
| 69 | BOOST_CHECK( tokens[1]==string("xX" ) ); |
| 70 | BOOST_CHECK( tokens[2]==string("xx" ) ); |
| 71 | |
| 72 | find_all( |
| 73 | Result&: tokens, |
| 74 | Input&: str1, |
| 75 | Search: "xx" ); |
| 76 | |
| 77 | BOOST_REQUIRE( tokens.size()==2 ); |
| 78 | BOOST_CHECK( tokens[0]==string("xx" ) ); |
| 79 | BOOST_CHECK( tokens[1]==string("xx" ) ); |
| 80 | |
| 81 | find_all( |
| 82 | Result&: vtokens, |
| 83 | Input&: str1, |
| 84 | Search: string("xx" ) ); |
| 85 | deep_compare( X: tokens, Y: vtokens ); |
| 86 | |
| 87 | #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) |
| 88 | // If using a compiler that supports forwarding references, we should be able to use rvalues, too |
| 89 | find_all( |
| 90 | Result&: tokens, |
| 91 | Input: string("xx-abc--xx-abb" ), |
| 92 | Search: "xx" ); |
| 93 | |
| 94 | BOOST_REQUIRE( tokens.size()==2 ); |
| 95 | BOOST_CHECK( tokens[0]==string("xx" ) ); |
| 96 | BOOST_CHECK( tokens[1]==string("xx" ) ); |
| 97 | |
| 98 | ifind_all( |
| 99 | Result&: tokens, |
| 100 | Input: string("Xx-abc--xX-abb-xx" ), |
| 101 | Search: "xx" ); |
| 102 | |
| 103 | BOOST_REQUIRE( tokens.size()==3 ); |
| 104 | BOOST_CHECK( tokens[0]==string("Xx" ) ); |
| 105 | BOOST_CHECK( tokens[1]==string("xX" ) ); |
| 106 | BOOST_CHECK( tokens[2]==string("xx" ) ); |
| 107 | #endif |
| 108 | |
| 109 | // split tests |
| 110 | split( |
| 111 | Result&: tokens, |
| 112 | Input&: str2, |
| 113 | Pred: is_any_of(Set: "xX" ), |
| 114 | eCompress: token_compress_on ); |
| 115 | |
| 116 | BOOST_REQUIRE( tokens.size()==4 ); |
| 117 | BOOST_CHECK( tokens[0]==string("" ) ); |
| 118 | BOOST_CHECK( tokens[1]==string("-abc--" ) ); |
| 119 | BOOST_CHECK( tokens[2]==string("-abb-" ) ); |
| 120 | BOOST_CHECK( tokens[3]==string("" ) ); |
| 121 | |
| 122 | split( |
| 123 | Result&: tokens, |
| 124 | Input&: pch1, |
| 125 | Pred: is_any_of(Set: "x" ), |
| 126 | eCompress: token_compress_on ); |
| 127 | |
| 128 | BOOST_REQUIRE( tokens.size()==3 ); |
| 129 | BOOST_CHECK( tokens[0]==string("" ) ); |
| 130 | BOOST_CHECK( tokens[1]==string("-abc--" ) ); |
| 131 | BOOST_CHECK( tokens[2]==string("-abb" ) ); |
| 132 | |
| 133 | split( |
| 134 | Result&: vtokens, |
| 135 | Input&: str1, |
| 136 | Pred: is_any_of(Set: "x" ), |
| 137 | eCompress: token_compress_on ); |
| 138 | deep_compare( X: tokens, Y: vtokens ); |
| 139 | |
| 140 | split( |
| 141 | Result&: tokens, |
| 142 | Input&: str1, |
| 143 | Pred: is_punct(), |
| 144 | eCompress: token_compress_off ); |
| 145 | |
| 146 | BOOST_REQUIRE( tokens.size()==5 ); |
| 147 | BOOST_CHECK( tokens[0]==string("xx" ) ); |
| 148 | BOOST_CHECK( tokens[1]==string("abc" ) ); |
| 149 | BOOST_CHECK( tokens[2]==string("" ) ); |
| 150 | BOOST_CHECK( tokens[3]==string("xx" ) ); |
| 151 | BOOST_CHECK( tokens[4]==string("abb" ) ); |
| 152 | |
| 153 | split( |
| 154 | Result&: tokens, |
| 155 | Input&: str3, |
| 156 | Pred: is_any_of(Set: "," ), |
| 157 | eCompress: token_compress_off); |
| 158 | |
| 159 | BOOST_REQUIRE( tokens.size()==1 ); |
| 160 | BOOST_CHECK( tokens[0]==string("xx" ) ); |
| 161 | |
| 162 | split( |
| 163 | Result&: tokens, |
| 164 | Input&: strempty, |
| 165 | Pred: is_punct(), |
| 166 | eCompress: token_compress_off); |
| 167 | |
| 168 | BOOST_REQUIRE( tokens.size()==1 ); |
| 169 | BOOST_CHECK( tokens[0]==string("" ) ); |
| 170 | |
| 171 | #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) |
| 172 | // If using a compiler that supports forwarding references, we should be able to use rvalues, too |
| 173 | split( |
| 174 | Result&: tokens, |
| 175 | Input: string("Xx-abc--xX-abb-xx" ), |
| 176 | Pred: is_any_of(Set: "xX" ), |
| 177 | eCompress: token_compress_on ); |
| 178 | |
| 179 | BOOST_REQUIRE( tokens.size()==4 ); |
| 180 | BOOST_CHECK( tokens[0]==string("" ) ); |
| 181 | BOOST_CHECK( tokens[1]==string("-abc--" ) ); |
| 182 | BOOST_CHECK( tokens[2]==string("-abb-" ) ); |
| 183 | BOOST_CHECK( tokens[3]==string("" ) ); |
| 184 | #endif |
| 185 | |
| 186 | |
| 187 | find_iterator<string::iterator> fiter=make_find_iterator(Collection&: str1, Finder: first_finder(Search: "xx" )); |
| 188 | find_iterator<string::iterator> fiter2; |
| 189 | |
| 190 | BOOST_CHECK(equals(*fiter, "xx" )); |
| 191 | ++fiter; |
| 192 | |
| 193 | fiter2 = fiter; |
| 194 | BOOST_CHECK(equals(*fiter, "xx" )); |
| 195 | BOOST_CHECK(equals(*fiter2, "xx" )); |
| 196 | |
| 197 | ++fiter; |
| 198 | BOOST_CHECK(fiter==find_iterator<string::iterator>()); |
| 199 | BOOST_CHECK(equals(*fiter2, "xx" )); |
| 200 | |
| 201 | ++fiter2; |
| 202 | BOOST_CHECK(fiter2==find_iterator<string::iterator>()); |
| 203 | |
| 204 | split_iterator<string::iterator> siter=make_split_iterator(Collection&: str1, Finder: token_finder(Pred: is_any_of(Set: "-" ), eCompress: token_compress_on)); |
| 205 | split_iterator<string::iterator> siter2; |
| 206 | BOOST_CHECK(equals(*siter, "xx" )); |
| 207 | ++siter; |
| 208 | |
| 209 | siter2 = siter; |
| 210 | BOOST_CHECK(equals(*siter, "abc" )); |
| 211 | BOOST_CHECK(equals(*siter2, "abc" )); |
| 212 | |
| 213 | ++siter; |
| 214 | BOOST_CHECK(equals(*siter, "xx" )); |
| 215 | BOOST_CHECK(equals(*siter2, "abc" )); |
| 216 | |
| 217 | ++siter; |
| 218 | BOOST_CHECK(equals(*siter, "abb" )); |
| 219 | ++siter; |
| 220 | BOOST_CHECK(siter==split_iterator<string::iterator>(siter)); |
| 221 | BOOST_CHECK(siter==split_iterator<string::iterator>()); |
| 222 | |
| 223 | // Make sure we work with forward iterators |
| 224 | // See bug #7989 |
| 225 | list<char> l1; |
| 226 | find_iterator<list<char>::iterator> liter=make_find_iterator(Collection&: l1, Finder: first_finder(Search: "xx" )); |
| 227 | } |
| 228 | |
| 229 | BOOST_AUTO_TEST_CASE( test_main ) |
| 230 | { |
| 231 | iterator_test(); |
| 232 | } |
| 233 | |