1/*============================================================================= 2 Copyright (c) 2001-2003 Joel de Guzman 3 Copyright (c) 2001-2003 Daniel Nuffer 4 http://spirit.sourceforge.net/ 5 6 Use, modification and distribution is subject to the Boost Software 7 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 8 http://www.boost.org/LICENSE_1_0.txt) 9=============================================================================*/ 10#ifndef BOOST_XPRESSIVE_SPIRIT_BASIC_CHSET_IPP 11#define BOOST_XPRESSIVE_SPIRIT_BASIC_CHSET_IPP 12 13/////////////////////////////////////////////////////////////////////////////// 14#include <bitset> 15#include <boost/xpressive/detail/utility/chset/basic_chset.hpp> 16 17/////////////////////////////////////////////////////////////////////////////// 18namespace boost { namespace xpressive { namespace detail 19{ 20 21/////////////////////////////////////////////////////////////////////////////// 22// 23// basic_chset: character set implementation 24// 25/////////////////////////////////////////////////////////////////////////////// 26template<typename Char> 27inline basic_chset<Char>::basic_chset() 28{ 29} 30 31////////////////////////////////// 32template<typename Char> 33inline basic_chset<Char>::basic_chset(basic_chset const &arg) 34 : rr_(arg.rr_) 35{ 36} 37 38////////////////////////////////// 39template<typename Char> 40inline bool basic_chset<Char>::empty() const 41{ 42 return this->rr_.empty(); 43} 44 45////////////////////////////////// 46template<typename Char> 47template<typename Traits> 48inline bool basic_chset<Char>::test(Char v, Traits const &, mpl::false_) const // case-sensitive 49{ 50 return this->rr_.test(v); 51} 52 53////////////////////////////////// 54template<typename Char> 55template<typename Traits> 56inline bool basic_chset<Char>::test(Char v, Traits const &tr, mpl::true_) const // case-insensitive 57{ 58 return this->rr_.test(v, tr); 59} 60 61////////////////////////////////// 62template<typename Char> 63inline void basic_chset<Char>::set(Char from, Char to) 64{ 65 this->rr_.set(range<Char>(from, to)); 66} 67 68////////////////////////////////// 69template<typename Char> 70template<typename Traits> 71inline void basic_chset<Char>::set(Char from, Char to, Traits const &) 72{ 73 this->rr_.set(range<Char>(from, to)); 74} 75 76////////////////////////////////// 77template<typename Char> 78inline void basic_chset<Char>::set(Char c) 79{ 80 this->rr_.set(range<Char>(c, c)); 81} 82 83////////////////////////////////// 84template<typename Char> 85template<typename Traits> 86inline void basic_chset<Char>::set(Char c, Traits const &) 87{ 88 this->rr_.set(range<Char>(c, c)); 89} 90 91////////////////////////////////// 92template<typename Char> 93inline void basic_chset<Char>::clear(Char c) 94{ 95 this->rr_.clear(range<Char>(c, c)); 96} 97 98////////////////////////////////// 99template<typename Char> 100template<typename Traits> 101inline void basic_chset<Char>::clear(Char c, Traits const &) 102{ 103 this->rr_.clear(range<Char>(c, c)); 104} 105 106////////////////////////////////// 107template<typename Char> 108inline void basic_chset<Char>::clear(Char from, Char to) 109{ 110 this->rr_.clear(range<Char>(from, to)); 111} 112 113////////////////////////////////// 114template<typename Char> 115template<typename Traits> 116inline void basic_chset<Char>::clear(Char from, Char to, Traits const &) 117{ 118 this->rr_.clear(range<Char>(from, to)); 119} 120 121////////////////////////////////// 122template<typename Char> 123inline void basic_chset<Char>::clear() 124{ 125 this->rr_.clear(); 126} 127 128///////////////////////////////// 129template<typename Char> 130inline void basic_chset<Char>::inverse() 131{ 132 // BUGBUG is this right? Does this handle icase correctly? 133 basic_chset<Char> inv; 134 inv.set((std::numeric_limits<Char>::min)(), (std::numeric_limits<Char>::max)()); 135 inv -= *this; 136 this->swap(inv); 137} 138 139///////////////////////////////// 140template<typename Char> 141inline void basic_chset<Char>::swap(basic_chset<Char> &that) 142{ 143 this->rr_.swap(that.rr_); 144} 145 146///////////////////////////////// 147template<typename Char> 148inline basic_chset<Char> & 149basic_chset<Char>::operator |=(basic_chset<Char> const &that) 150{ 151 typedef typename range_run<Char>::const_iterator const_iterator; 152 for(const_iterator iter = that.rr_.begin(); iter != that.rr_.end(); ++iter) 153 { 154 this->rr_.set(*iter); 155 } 156 return *this; 157} 158 159///////////////////////////////// 160template<typename Char> 161inline basic_chset<Char> & 162basic_chset<Char>::operator &=(basic_chset<Char> const &that) 163{ 164 basic_chset<Char> inv; 165 inv.set((std::numeric_limits<Char>::min)(), (std::numeric_limits<Char>::max)()); 166 inv -= that; 167 *this -= inv; 168 return *this; 169} 170 171///////////////////////////////// 172template<typename Char> 173inline basic_chset<Char> & 174basic_chset<Char>::operator -=(basic_chset<Char> const &that) 175{ 176 typedef typename range_run<Char>::const_iterator const_iterator; 177 for(const_iterator iter = that.rr_.begin(); iter != that.rr_.end(); ++iter) 178 { 179 this->rr_.clear(*iter); 180 } 181 return *this; 182} 183 184///////////////////////////////// 185template<typename Char> 186inline basic_chset<Char> & 187basic_chset<Char>::operator ^=(basic_chset<Char> const &that) 188{ 189 basic_chset bma = that; 190 bma -= *this; 191 *this -= that; 192 *this |= bma; 193 return *this; 194} 195 196#if(CHAR_BIT == 8) 197 198/////////////////////////////////////////////////////////////////////////////// 199// 200// basic_chset: specializations for 8 bit chars using std::bitset 201// 202/////////////////////////////////////////////////////////////////////////////// 203template<typename Char> 204inline basic_chset_8bit<Char>::basic_chset_8bit() 205{ 206} 207 208///////////////////////////////// 209template<typename Char> 210inline basic_chset_8bit<Char>::basic_chset_8bit(basic_chset_8bit<Char> const &arg) 211 : bset_(arg.bset_) 212{ 213} 214 215///////////////////////////////// 216template<typename Char> 217inline bool basic_chset_8bit<Char>::empty() const 218{ 219 return !this->bset_.any(); 220} 221 222///////////////////////////////// 223template<typename Char> 224template<typename Traits> 225inline bool basic_chset_8bit<Char>::test(Char v, Traits const &, mpl::false_) const // case-sensitive 226{ 227 return this->bset_.test((unsigned char)v); 228} 229 230///////////////////////////////// 231template<typename Char> 232template<typename Traits> 233inline bool basic_chset_8bit<Char>::test(Char v, Traits const &tr, mpl::true_) const // case-insensitive 234{ 235 return this->bset_.test((unsigned char)tr.translate_nocase(v)); 236} 237 238///////////////////////////////// 239template<typename Char> 240inline void basic_chset_8bit<Char>::set(Char from, Char to) 241{ 242 for(int i = from; i <= to; ++i) 243 { 244 this->bset_.set((unsigned char)i); 245 } 246} 247 248///////////////////////////////// 249template<typename Char> 250template<typename Traits> 251inline void basic_chset_8bit<Char>::set(Char from, Char to, Traits const &tr) 252{ 253 for(int i = from; i <= to; ++i) 254 { 255 this->bset_.set((unsigned char)tr.translate_nocase((Char)i)); 256 } 257} 258 259///////////////////////////////// 260template<typename Char> 261inline void basic_chset_8bit<Char>::set(Char c) 262{ 263 this->bset_.set((unsigned char)c); 264} 265 266///////////////////////////////// 267template<typename Char> 268template<typename Traits> 269inline void basic_chset_8bit<Char>::set(Char c, Traits const &tr) 270{ 271 this->bset_.set((unsigned char)tr.translate_nocase(c)); 272} 273 274///////////////////////////////// 275template<typename Char> 276inline void basic_chset_8bit<Char>::clear(Char from, Char to) 277{ 278 for(int i = from; i <= to; ++i) 279 { 280 this->bset_.reset((unsigned char)i); 281 } 282} 283 284///////////////////////////////// 285template<typename Char> 286template<typename Traits> 287inline void basic_chset_8bit<Char>::clear(Char from, Char to, Traits const &tr) 288{ 289 for(int i = from; i <= to; ++i) 290 { 291 this->bset_.reset((unsigned char)tr.translate_nocase((Char)i)); 292 } 293} 294 295///////////////////////////////// 296template<typename Char> 297inline void basic_chset_8bit<Char>::clear(Char c) 298{ 299 this->bset_.reset((unsigned char)c); 300} 301 302///////////////////////////////// 303template<typename Char> 304template<typename Traits> 305inline void basic_chset_8bit<Char>::clear(Char c, Traits const &tr) 306{ 307 this->bset_.reset((unsigned char)tr.tranlsate_nocase(c)); 308} 309 310///////////////////////////////// 311template<typename Char> 312inline void basic_chset_8bit<Char>::clear() 313{ 314 this->bset_.reset(); 315} 316 317///////////////////////////////// 318template<typename Char> 319inline void basic_chset_8bit<Char>::inverse() 320{ 321 this->bset_.flip(); 322} 323 324///////////////////////////////// 325template<typename Char> 326inline void basic_chset_8bit<Char>::swap(basic_chset_8bit<Char> &that) 327{ 328 std::swap(this->bset_, that.bset_); 329} 330 331///////////////////////////////// 332template<typename Char> 333inline basic_chset_8bit<Char> & 334basic_chset_8bit<Char>::operator |=(basic_chset_8bit<Char> const &that) 335{ 336 this->bset_ |= that.bset_; 337 return *this; 338} 339 340///////////////////////////////// 341template<typename Char> 342inline basic_chset_8bit<Char> & 343basic_chset_8bit<Char>::operator &=(basic_chset_8bit<Char> const &that) 344{ 345 this->bset_ &= that.bset_; 346 return *this; 347} 348 349///////////////////////////////// 350template<typename Char> 351inline basic_chset_8bit<Char> & 352basic_chset_8bit<Char>::operator -=(basic_chset_8bit<Char> const &that) 353{ 354 this->bset_ &= ~that.bset_; 355 return *this; 356} 357 358///////////////////////////////// 359template<typename Char> 360inline basic_chset_8bit<Char> & 361basic_chset_8bit<Char>::operator ^=(basic_chset_8bit<Char> const &that) 362{ 363 this->bset_ ^= that.bset_; 364 return *this; 365} 366 367template<typename Char> 368inline std::bitset<256> const & 369basic_chset_8bit<Char>::base() const 370{ 371 return this->bset_; 372} 373 374#endif // if(CHAR_BIT == 8) 375 376 377/////////////////////////////////////////////////////////////////////////////// 378// helpers 379template<typename Char, typename Traits> 380inline void set_char(basic_chset<Char> &chset, Char ch, Traits const &tr, bool icase) 381{ 382 icase ? chset.set(ch, tr) : chset.set(ch); 383} 384 385template<typename Char, typename Traits> 386inline void set_range(basic_chset<Char> &chset, Char from, Char to, Traits const &tr, bool icase) 387{ 388 icase ? chset.set(from, to, tr) : chset.set(from, to); 389} 390 391template<typename Char, typename Traits> 392inline void set_class(basic_chset<Char> &chset, typename Traits::char_class_type char_class, bool no, Traits const &tr) 393{ 394 BOOST_MPL_ASSERT_RELATION(1, ==, sizeof(Char)); 395 for(std::size_t i = 0; i <= UCHAR_MAX; ++i) 396 { 397 typedef typename std::char_traits<Char>::int_type int_type; 398 Char ch = std::char_traits<Char>::to_char_type(static_cast<int_type>(i)); 399 if(no != tr.isctype(ch, char_class)) 400 { 401 chset.set(ch); 402 } 403 } 404} 405 406}}} // namespace boost::xpressive::detail 407 408#endif 409 410