4 |
#include <string> |
#include <string> |
5 |
#include <iostream> |
#include <iostream> |
6 |
#include <cctype> |
#include <cctype> |
7 |
|
#include <strings.h> |
8 |
|
|
9 |
// case insensitive character traits |
// case insensitive character traits |
10 |
// inherited copy (preserves case), |
// inherited copy (preserves case), |
11 |
// case insensitive comparison, search |
// case insensitive comparison, search |
12 |
struct traits_nocase : std::char_traits<char> |
struct traits_nocase : std::char_traits<char> |
13 |
{ |
{ |
14 |
static bool eq( const char& c1, const char& c2 ) |
static bool eq( const char& c1, const char& c2 ) |
15 |
{ return toupper(c1) == toupper(c2) ; } |
{ |
16 |
static bool lt( const char& c1, const char& c2 ) |
return toupper(c1) == toupper(c2) ; |
17 |
{ return toupper(c1) < toupper(c2) ; } |
} |
18 |
static int compare( const char* s1, const char* s2, size_t N ) |
static bool lt( const char& c1, const char& c2 ) |
19 |
{ |
{ |
20 |
return strncasecmp( s1, s2, N ) ; // posix |
return toupper(c1) < toupper(c2) ; |
21 |
// mirosoft C++ - use _strnicmp instead |
} |
22 |
} |
static int compare( const char* s1, const char* s2, size_t N ) |
23 |
static const char* find( const char* s, size_t N, const char& a ) |
{ |
24 |
{ |
return strncasecmp( s1, s2, N ) ; // posix |
25 |
for( size_t i=0 ; i<N ; ++i ) |
// mirosoft C++ - use _strnicmp instead |
26 |
if( toupper(s[i]) == toupper(a) ) return s+i ; |
} |
27 |
return 0 ; |
static const char* find( const char* s, size_t N, const char& a ) |
28 |
} |
{ |
29 |
static bool eq_int_type ( const int_type& c1, const int_type& c2 ) |
for ( size_t i=0 ; i<N ; ++i ) |
30 |
{ return toupper(c1) == toupper(c2) ; } |
if ( toupper(s[i]) == toupper(a) ) return s+i ; |
31 |
|
return 0 ; |
32 |
|
} |
33 |
|
static bool eq_int_type ( const int_type& c1, const int_type& c2 ) |
34 |
|
{ |
35 |
|
return toupper(c1) == toupper(c2) ; |
36 |
|
} |
37 |
}; |
}; |
38 |
|
|
39 |
// string preserves case; comparisons are case insensitive |
// string preserves case; comparisons are case insensitive |
40 |
typedef std::basic_string< char, traits_nocase > string_nocase ; |
typedef std::basic_string< char, traits_nocase > string_nocase ; |
41 |
|
|
42 |
// make string_nocase work like a std::string |
// make string_nocase work like a std::string |
43 |
// with streams using std::char_traits |
// with streams using std::char_traits |
44 |
// std::basic_istream< char, std::char_traits<char> > (std::istream) and |
// std::basic_istream< char, std::char_traits<char> > (std::istream) and |
45 |
// std::basic_ostream< char, std::char_traits<char> > (std::ostream) |
// std::basic_ostream< char, std::char_traits<char> > (std::ostream) |
46 |
inline std::ostream& operator<< ( std::ostream& stm, const string_nocase& str ) |
inline std::ostream& operator<< ( std::ostream& stm, const string_nocase& str ) |
47 |
{ return stm << reinterpret_cast<const std::string&>(str) ; } |
{ |
48 |
|
return stm << reinterpret_cast<const std::string&>(str) ; |
49 |
|
} |
50 |
|
|
51 |
inline std::istream& operator>> ( std::istream& stm, string_nocase& str ) |
inline std::istream& operator>> ( std::istream& stm, string_nocase& str ) |
52 |
{ |
{ |
53 |
std::string s ; stm >> s ; |
std::string s ; |
54 |
if(stm) str.assign(s.begin(),s.end()) ; |
stm >> s ; |
55 |
return stm ; |
if (stm) str.assign(s.begin(),s.end()) ; |
56 |
|
return stm ; |
57 |
} |
} |
58 |
|
|
59 |
inline std::istream& getline( std::istream& stm, string_nocase& str ) |
inline std::istream& getline( std::istream& stm, string_nocase& str ) |
60 |
{ |
{ |
61 |
std::string s ; std::getline(stm,s) ; |
std::string s ; |
62 |
if(stm) str.assign(s.begin(),s.end()) ; |
std::getline(stm,s) ; |
63 |
return stm ; |
if (stm) str.assign(s.begin(),s.end()) ; |
64 |
|
return stm ; |
65 |
} |
} |
66 |
|
|
67 |
#endif // __STRING_NOCASE_H__ |
#endif // __STRING_NOCASE_H__ |