iv-phonic 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. data/.autotest +24 -0
  2. data/Manifest.txt +49 -0
  3. data/README.rdoc +32 -0
  4. data/Rakefile +54 -0
  5. data/ext/include/iv/algorithm.h +23 -0
  6. data/ext/include/iv/alloc.h +200 -0
  7. data/ext/include/iv/any.h +71 -0
  8. data/ext/include/iv/ast-factory.h +277 -0
  9. data/ext/include/iv/ast-fwd.h +92 -0
  10. data/ext/include/iv/ast-serializer.h +579 -0
  11. data/ext/include/iv/ast-visitor.h +121 -0
  12. data/ext/include/iv/ast.h +1127 -0
  13. data/ext/include/iv/chars.h +83 -0
  14. data/ext/include/iv/cmdline.h +830 -0
  15. data/ext/include/iv/conversions.h +308 -0
  16. data/ext/include/iv/dtoa.h +20 -0
  17. data/ext/include/iv/enable_if.h +18 -0
  18. data/ext/include/iv/errors.h +15 -0
  19. data/ext/include/iv/fixedcontainer.h +42 -0
  20. data/ext/include/iv/functor.h +29 -0
  21. data/ext/include/iv/lexer.h +1281 -0
  22. data/ext/include/iv/location.h +23 -0
  23. data/ext/include/iv/mt19937.h +175 -0
  24. data/ext/include/iv/noncopyable.h +30 -0
  25. data/ext/include/iv/none.h +10 -0
  26. data/ext/include/iv/parser.h +2150 -0
  27. data/ext/include/iv/source.h +27 -0
  28. data/ext/include/iv/space.h +178 -0
  29. data/ext/include/iv/static_assert.h +30 -0
  30. data/ext/include/iv/stringpiece.h +385 -0
  31. data/ext/include/iv/token.h +311 -0
  32. data/ext/include/iv/ucdata.h +58 -0
  33. data/ext/include/iv/uchar.h +8 -0
  34. data/ext/include/iv/ustring.h +28 -0
  35. data/ext/include/iv/ustringpiece.h +9 -0
  36. data/ext/include/iv/utils.h +83 -0
  37. data/ext/include/iv/xorshift.h +74 -0
  38. data/ext/iv/phonic/ast-fwd.h +21 -0
  39. data/ext/iv/phonic/ast.h +10 -0
  40. data/ext/iv/phonic/creator.h +530 -0
  41. data/ext/iv/phonic/encoding.h +110 -0
  42. data/ext/iv/phonic/extconf.rb +5 -0
  43. data/ext/iv/phonic/factory.h +247 -0
  44. data/ext/iv/phonic/parser.h +12 -0
  45. data/ext/iv/phonic/phonic.cc +69 -0
  46. data/ext/iv/phonic/rnode.h +15 -0
  47. data/ext/iv/phonic/rparser.h +48 -0
  48. data/ext/iv/phonic/source.h +146 -0
  49. data/test/test_iv_phonic.rb +32 -0
  50. metadata +159 -0
@@ -0,0 +1,27 @@
1
+ #ifndef _IV_SOURCE_H_
2
+ #define _IV_SOURCE_H_
3
+ #include <cstddef>
4
+ #include <cassert>
5
+ #include <string>
6
+ #include "ustring.h"
7
+ #include "ustringpiece.h"
8
+
9
+ namespace iv {
10
+ namespace core {
11
+
12
+ class BasicSource {
13
+ public:
14
+ static const int kEOS = -1;
15
+ virtual ~BasicSource() = 0;
16
+
17
+ virtual uc16 Get(std::size_t pos) const = 0;
18
+ virtual std::size_t size() const = 0;
19
+ virtual const std::string& filename() const = 0;
20
+ virtual UStringPiece SubString(std::size_t n,
21
+ std::size_t len = std::string::npos) const = 0;
22
+ };
23
+
24
+ inline BasicSource::~BasicSource() { }
25
+
26
+ } } // namespace iv::core
27
+ #endif // _IV_SOURCE_H_
@@ -0,0 +1,178 @@
1
+ #ifndef _IV_SPACE_H_
2
+ #define _IV_SPACE_H_
3
+ #include <cassert>
4
+ #include <cstddef>
5
+ #include <new>
6
+ #include <vector>
7
+ #include <map>
8
+ #include <list>
9
+ #include <algorithm>
10
+ #include <string>
11
+ #include <limits>
12
+ #include <functional>
13
+ #include <tr1/unordered_map>
14
+ #include <tr1/functional>
15
+ #include "uchar.h"
16
+ #include "conversions.h"
17
+
18
+ namespace iv {
19
+ namespace core {
20
+
21
+ class SpaceObject {
22
+ public:
23
+ template<typename Factory>
24
+ void* operator new(std::size_t size, Factory* factory) {
25
+ return factory->New(size);
26
+ }
27
+ void operator delete(void*, std::size_t) {
28
+ UNREACHABLE();
29
+ }
30
+ };
31
+
32
+ template<class Factory, class T>
33
+ class SpaceAllocator {
34
+ public:
35
+ typedef std::size_t size_type;
36
+ typedef std::ptrdiff_t difference_type;
37
+ typedef T* pointer;
38
+ typedef const T* const_pointer;
39
+ typedef T& reference;
40
+ typedef const T& const_reference;
41
+ typedef T value_type;
42
+ typedef SpaceAllocator<Factory, T> this_type;
43
+ template<class U>
44
+ struct rebind {
45
+ typedef SpaceAllocator<Factory, U> other;
46
+ };
47
+
48
+ SpaceAllocator() : space_(NULL) { }
49
+ explicit SpaceAllocator(Factory* factory) throw() : space_(factory) { }
50
+
51
+ template<class U>
52
+ SpaceAllocator(const SpaceAllocator<Factory, U>& alloc) throw() // NOLINT
53
+ : space_(alloc.space()) {
54
+ }
55
+
56
+ ~SpaceAllocator() throw() {}
57
+
58
+ inline pointer address(reference x) const {
59
+ return &x;
60
+ }
61
+
62
+ inline const_pointer address(const_reference x) const {
63
+ return &x;
64
+ }
65
+
66
+ inline pointer allocate(size_type n, const void* = 0) {
67
+ assert(space_);
68
+ return reinterpret_cast<pointer>(space_->New(n * sizeof(T)));
69
+ }
70
+
71
+ inline void deallocate(pointer, size_type) { }
72
+
73
+ inline size_type max_size() const {
74
+ return std::numeric_limits<size_type>::max() / sizeof(T);
75
+ }
76
+
77
+ inline void construct(pointer p, const T& val) {
78
+ new(reinterpret_cast<void*>(p)) T(val);
79
+ }
80
+
81
+ inline void destroy(pointer p) {
82
+ (p)->~T();
83
+ }
84
+
85
+ inline char* _Charalloc(size_type n) {
86
+ return allocate(n);
87
+ }
88
+
89
+ template<typename Other>
90
+ inline this_type& operator=(const SpaceAllocator<Factory, Other>& rhs) {
91
+ if (this != &rhs) {
92
+ this_type(rhs).Swap(*this);
93
+ }
94
+ return *this;
95
+ }
96
+
97
+ Factory* space() const {
98
+ return space_;
99
+ }
100
+
101
+ protected:
102
+ void Swap(this_type& rhs) {
103
+ using std::swap;
104
+ swap(space_, rhs.space_);
105
+ }
106
+ Factory* space_;
107
+
108
+ private:
109
+ void operator=(const SpaceAllocator&);
110
+ };
111
+
112
+ template <typename Factory, typename T>
113
+ bool operator==(const SpaceAllocator<Factory, T>& lhs,
114
+ const SpaceAllocator<Factory, T>& rhs) {
115
+ return true;
116
+ }
117
+
118
+ template <typename Factory, typename T>
119
+ bool operator!=(const SpaceAllocator<Factory, T>& lhs,
120
+ const SpaceAllocator<Factory, T>& rhs) {
121
+ return false;
122
+ }
123
+
124
+ template<typename Factory, typename T>
125
+ struct SpaceVector {
126
+ typedef std::vector<T, SpaceAllocator<Factory, T> > type;
127
+ };
128
+
129
+ template<typename Factory, typename T1, typename T2>
130
+ struct SpaceMap {
131
+ typedef std::map<T1,
132
+ T2,
133
+ std::less<T1>,
134
+ SpaceAllocator<Factory, std::pair<const T1, T2> > > type;
135
+ };
136
+
137
+ template<typename Factory, typename T1, typename T2>
138
+ struct SpaceHashMap {
139
+ typedef std::tr1::unordered_map<T1,
140
+ T2,
141
+ std::tr1::hash<T1>,
142
+ std::equal_to<T1>,
143
+ SpaceAllocator<
144
+ Factory,
145
+ std::pair<const T1, T2> > > type;
146
+ };
147
+
148
+ template<typename Factory, typename T>
149
+ struct SpaceList {
150
+ typedef std::list<T, SpaceAllocator<Factory, T> > type;
151
+ };
152
+
153
+ template<typename Factory>
154
+ struct SpaceUString {
155
+ typedef std::basic_string<uc16,
156
+ std::char_traits<uc16>,
157
+ SpaceAllocator<Factory, uc16> > type;
158
+ };
159
+
160
+ } } // namespace iv::core
161
+ namespace std {
162
+ namespace tr1 {
163
+ // template specialization for SpaceUString in std::tr1::unordered_map
164
+ // allowed in section 17.4.3.1
165
+ template<typename Factory>
166
+ struct hash<std::basic_string<iv::uc16,
167
+ std::char_traits<iv::uc16>,
168
+ iv::core::SpaceAllocator<Factory, iv::uc16> > > {
169
+ typedef std::basic_string<iv::uc16,
170
+ std::char_traits<iv::uc16>,
171
+ iv::core::SpaceAllocator<Factory, iv::uc16> >
172
+ argument_type;
173
+ std::size_t operator()(const argument_type& x) const {
174
+ return iv::core::StringToHash(x);
175
+ }
176
+ };
177
+ } } // namespace std::tr1
178
+ #endif // _IV_SPACE_H_
@@ -0,0 +1,30 @@
1
+ #ifndef _IV_STATICASSERT_H_
2
+ #define _IV_STATICASSERT_H_
3
+ namespace iv {
4
+ namespace detail {
5
+ template<bool b>
6
+ struct StaticAssertFailure;
7
+
8
+ template<>
9
+ struct StaticAssertFailure<true> {
10
+ enum {
11
+ value = 1
12
+ };
13
+ };
14
+
15
+ template<int x>
16
+ struct StaticAssertTest {
17
+ };
18
+
19
+ } } // namespace iv::detail
20
+
21
+ #ifndef IV_CONCAT
22
+ #define IV_CONCAT1(x, y) x##y
23
+ #define IV_CONCAT(x, y) IV_CONCAT1(x, y)
24
+ #endif // IV_CONCAT
25
+ #define IV_STATIC_ASSERT(cond)\
26
+ typedef ::iv::detail::StaticAssertTest\
27
+ <sizeof(::iv::detail::StaticAssertFailure<static_cast<bool>(cond)>)>\
28
+ IV_CONCAT(StaticAssertTypedef, __LINE__)
29
+
30
+ #endif // _IV_STATICASSERT_H_
@@ -0,0 +1,385 @@
1
+ #ifndef IV_STRINGPIECE_H_
2
+ #define IV_STRINGPIECE_H_
3
+ #pragma once
4
+
5
+ #include <algorithm>
6
+ #include <iosfwd>
7
+ #include <string>
8
+ #include <iterator>
9
+ #include <limits>
10
+
11
+ namespace iv {
12
+ namespace core {
13
+
14
+ template<class CharT, class Traits = std::char_traits<CharT> >
15
+ class BasicStringPiece {
16
+ public:
17
+ typedef size_t size_type;
18
+ typedef BasicStringPiece<CharT, Traits> this_type;
19
+
20
+ private:
21
+ const CharT* ptr_;
22
+ size_type length_;
23
+
24
+ public:
25
+ // We provide non-explicit singleton constructors so users can pass
26
+ // in a "const char*" or a "string" wherever a "StringPiece" is
27
+ // expected.
28
+ BasicStringPiece() : ptr_(NULL), length_(0) { }
29
+ BasicStringPiece(const CharT* str) // NOLINT
30
+ : ptr_(str), length_((str == NULL) ? 0 : Traits::length(str)) { }
31
+ template<typename Alloc>
32
+ BasicStringPiece(const std::basic_string<CharT, Traits, Alloc>& str) // NOLINT
33
+ : ptr_(str.data()), length_(str.size()) { }
34
+ BasicStringPiece(const CharT* offset, size_type len)
35
+ : ptr_(offset), length_(len) { }
36
+ BasicStringPiece(const BasicStringPiece& str)
37
+ : ptr_(str.ptr_), length_(str.length_) { }
38
+
39
+ // data() may return a pointer to a buffer with embedded NULs, and the
40
+ // returned buffer may or may not be null terminated. Therefore it is
41
+ // typically a mistake to pass data() to a routine that expects a NUL
42
+ // terminated string.
43
+ const CharT* data() const { return ptr_; }
44
+ size_type size() const { return length_; }
45
+ size_type length() const { return length_; }
46
+ bool empty() const { return length_ == 0; }
47
+
48
+ void clear() {
49
+ ptr_ = NULL;
50
+ length_ = 0;
51
+ }
52
+ void set(const CharT* data, size_type len) {
53
+ ptr_ = data;
54
+ length_ = len;
55
+ }
56
+ void set(const CharT* str) {
57
+ ptr_ = str;
58
+ length_ = str ? Traits::length(str) : 0;
59
+ }
60
+ void set(const void* data, size_type len) {
61
+ ptr_ = reinterpret_cast<const CharT*>(data);
62
+ length_ = len;
63
+ }
64
+
65
+ CharT operator[](size_type i) const { return ptr_[i]; }
66
+
67
+ void remove_prefix(size_type n) {
68
+ ptr_ += n;
69
+ length_ -= n;
70
+ }
71
+
72
+ void remove_suffix(size_type n) {
73
+ length_ -= n;
74
+ }
75
+
76
+ int compare(const this_type& x) const {
77
+ int r = wordmemcmp(ptr_, x.ptr_, std::min(length_, x.length_));
78
+ if (r == 0) {
79
+ if (length_ < x.length_) r = -1;
80
+ else if (length_ > x.length_) r = +1;
81
+ }
82
+ return r;
83
+ }
84
+
85
+ std::basic_string<CharT, Traits> as_string() const {
86
+ // std::basic_string<CharT> doesn't like to
87
+ // take a NULL pointer even with a 0 size.
88
+ if (!empty()) {
89
+ return std::basic_string<CharT, Traits>(data(), size());
90
+ } else {
91
+ return std::basic_string<CharT, Traits>();
92
+ }
93
+ }
94
+
95
+ template<typename Alloc>
96
+ void CopyToString(std::basic_string<CharT, Traits, Alloc>* target) const {
97
+ if (!empty()) {
98
+ target->assign(data(), size());
99
+ } else {
100
+ target->assign(NULL, 0);
101
+ }
102
+ }
103
+
104
+ template<typename Alloc>
105
+ void AppendToString(std::basic_string<CharT, Traits, Alloc>* target) const {
106
+ if (!empty())
107
+ target->append(data(), size());
108
+ }
109
+
110
+ // Does "this" start with "x"
111
+ bool starts_with(const this_type& x) const {
112
+ return ((length_ >= x.length_) &&
113
+ (wordmemcmp(ptr_, x.ptr_, x.length_) == 0));
114
+ }
115
+
116
+ // Does "this" end with "x"
117
+ bool ends_with(const this_type& x) const {
118
+ return ((length_ >= x.length_) &&
119
+ (wordmemcmp(ptr_ + (length_-x.length_), x.ptr_, x.length_) == 0));
120
+ }
121
+
122
+ // standard STL container boilerplate
123
+ typedef CharT value_type;
124
+ typedef const CharT* pointer;
125
+ typedef const CharT& reference;
126
+ typedef const CharT& const_reference;
127
+ typedef ptrdiff_t difference_type;
128
+ static const size_type npos = -1;
129
+ typedef const CharT* const_iterator;
130
+ typedef const CharT* iterator;
131
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
132
+ typedef std::reverse_iterator<iterator> reverse_iterator;
133
+ iterator begin() const { return ptr_; }
134
+ iterator end() const { return ptr_ + length_; }
135
+ const_reverse_iterator rbegin() const {
136
+ return const_reverse_iterator(ptr_ + length_);
137
+ }
138
+ const_reverse_iterator rend() const {
139
+ return const_reverse_iterator(ptr_);
140
+ }
141
+
142
+ size_type max_size() const { return length_; }
143
+ size_type capacity() const { return length_; }
144
+
145
+ size_type copy(CharT* buf, size_type n, size_type pos = 0) const {
146
+ size_type ret = std::min(length_ - pos, n);
147
+ memcpy(buf, ptr_ + pos, ret);
148
+ return ret;
149
+ }
150
+
151
+ size_type find(const this_type& s, size_type pos = 0) const {
152
+ if (pos > length_)
153
+ return npos;
154
+
155
+ const CharT * result = std::search(ptr_ + pos, ptr_ + length_,
156
+ s.ptr_, s.ptr_ + s.length_);
157
+ const size_type xpos = result - ptr_;
158
+ return xpos + s.length_ <= length_ ? xpos : npos;
159
+ }
160
+
161
+ size_type find(CharT c, size_type pos = 0) const {
162
+ if (pos >= length_)
163
+ return npos;
164
+
165
+ const CharT * result = std::find(ptr_ + pos, ptr_ + length_, c);
166
+ return result != ptr_ + length_ ? static_cast<size_t>(result - ptr_) : npos;
167
+ }
168
+
169
+ size_type rfind(const this_type& s, size_type pos = npos) const {
170
+ if (length_ < s.length_)
171
+ return npos;
172
+
173
+ if (s.empty())
174
+ return std::min(length_, pos);
175
+
176
+ const CharT * last = ptr_ + std::min(length_ - s.length_, pos) + s.length_;
177
+ const CharT * result = std::find_end(ptr_, last,
178
+ s.ptr_, s.ptr_ + s.length_);
179
+ return result != last ? static_cast<size_t>(result - ptr_) : npos;
180
+ }
181
+
182
+ size_type rfind(CharT c, size_type pos = npos) const {
183
+ if (length_ == 0)
184
+ return npos;
185
+
186
+ for (size_type i = std::min(pos, length_ - 1); ; --i) {
187
+ if (ptr_[i] == c)
188
+ return i;
189
+ if (i == 0)
190
+ break;
191
+ }
192
+ return npos;
193
+ }
194
+
195
+ size_type find_first_of(const this_type& s,
196
+ size_type pos) const {
197
+ if (length_ == 0 || s.length_ == 0)
198
+ return npos;
199
+
200
+ // Avoid the cost of BuildLookupTable() for a single-character search.
201
+ if (s.length_ == 1)
202
+ return find_first_of(s.ptr_[0], pos);
203
+
204
+ bool lookup[std::numeric_limits<CharT>::max() + 1] = { false };
205
+ BuildLookupTable(s, lookup);
206
+ for (size_type i = pos; i < length_; ++i) {
207
+ if (lookup[static_cast<CharT>(ptr_[i])]) {
208
+ return i;
209
+ }
210
+ }
211
+ return npos;
212
+ }
213
+
214
+
215
+ size_type find_first_of(CharT c, size_type pos = 0) const {
216
+ return find(c, pos);
217
+ }
218
+
219
+ size_type find_first_not_of(const this_type& s,
220
+ size_type pos) const {
221
+ if (length_ == 0)
222
+ return npos;
223
+
224
+ if (s.length_ == 0)
225
+ return 0;
226
+
227
+ // Avoid the cost of BuildLookupTable() for a single-character search.
228
+ if (s.length_ == 1)
229
+ return find_first_not_of(s.ptr_[0], pos);
230
+
231
+ bool lookup[std::numeric_limits<CharT>::max() + 1] = { false };
232
+ BuildLookupTable(s, lookup);
233
+ for (size_type i = pos; i < length_; ++i) {
234
+ if (!lookup[static_cast<CharT>(ptr_[i])]) {
235
+ return i;
236
+ }
237
+ }
238
+ return npos;
239
+ }
240
+
241
+ size_type find_first_not_of(CharT c, size_type pos) const {
242
+ if (length_ == 0)
243
+ return npos;
244
+
245
+ for (; pos < length_; ++pos) {
246
+ if (ptr_[pos] != c) {
247
+ return pos;
248
+ }
249
+ }
250
+ return npos;
251
+ }
252
+
253
+ size_type find_last_of(const this_type& s, size_type pos) const {
254
+ if (length_ == 0 || s.length_ == 0)
255
+ return npos;
256
+
257
+ // Avoid the cost of BuildLookupTable() for a single-character search.
258
+ if (s.length_ == 1)
259
+ return find_last_of(s.ptr_[0], pos);
260
+
261
+ bool lookup[std::numeric_limits<CharT>::max() + 1] = { false };
262
+ BuildLookupTable(s, lookup);
263
+ for (size_type i = std::min(pos, length_ - 1); ; --i) {
264
+ if (lookup[static_cast<CharT>(ptr_[i])])
265
+ return i;
266
+ if (i == 0)
267
+ break;
268
+ }
269
+ return npos;
270
+ }
271
+
272
+ size_type find_last_of(CharT c, size_type pos = npos) const {
273
+ return rfind(c, pos);
274
+ }
275
+
276
+ size_type find_last_not_of(const this_type& s,
277
+ size_type pos) const {
278
+ if (length_ == 0)
279
+ return npos;
280
+
281
+ size_type i = std::min(pos, length_ - 1);
282
+ if (s.length_ == 0)
283
+ return i;
284
+
285
+ // Avoid the cost of BuildLookupTable() for a single-character search.
286
+ if (s.length_ == 1)
287
+ return find_last_not_of(s.ptr_[0], pos);
288
+
289
+ bool lookup[std::numeric_limits<CharT>::max() + 1] = { false };
290
+ BuildLookupTable(s, lookup);
291
+ for (; ; --i) {
292
+ if (!lookup[static_cast<CharT>(ptr_[i])])
293
+ return i;
294
+ if (i == 0)
295
+ break;
296
+ }
297
+ return npos;
298
+ }
299
+
300
+ size_type find_last_not_of(CharT c, size_type pos) const {
301
+ if (length_ == 0)
302
+ return npos;
303
+
304
+ for (size_type i = std::min(pos, length_ - 1); ; --i) {
305
+ if (ptr_[i] != c)
306
+ return i;
307
+ if (i == 0)
308
+ break;
309
+ }
310
+ return npos;
311
+ }
312
+
313
+ this_type substr(size_type pos, size_type n) const {
314
+ if (pos > length_) pos = length_;
315
+ if (n > length_ - pos) n = length_ - pos;
316
+ return this_type(ptr_ + pos, n);
317
+ }
318
+
319
+ static int wordmemcmp(const CharT * p, const CharT * p2, size_type N) {
320
+ return memcmp(p, p2, N);
321
+ }
322
+
323
+ static inline void BuildLookupTable(const this_type& characters_wanted,
324
+ bool* table) {
325
+ const size_type length = characters_wanted.length();
326
+ const CharT * const data = characters_wanted.data();
327
+ for (size_type i = 0; i < length; ++i) {
328
+ table[static_cast<CharT>(data[i])] = true;
329
+ }
330
+ }
331
+ };
332
+
333
+ template<class CharT>
334
+ bool operator==(const BasicStringPiece<CharT>& x,
335
+ const BasicStringPiece<CharT>& y) {
336
+ if (x.size() != y.size())
337
+ return false;
338
+
339
+ return BasicStringPiece<CharT>::wordmemcmp(x.data(), y.data(), x.size()) == 0;
340
+ }
341
+
342
+ template<class CharT>
343
+ inline bool operator!=(const BasicStringPiece<CharT>& x,
344
+ const BasicStringPiece<CharT>& y) {
345
+ return !(x == y);
346
+ }
347
+
348
+ template<class CharT>
349
+ inline bool operator<(const BasicStringPiece<CharT>& x,
350
+ const BasicStringPiece<CharT>& y) {
351
+ const int r = BasicStringPiece<CharT>::wordmemcmp(x.data(), y.data(),
352
+ std::min(x.size(), y.size()));
353
+ return ((r < 0) || ((r == 0) && (x.size() < y.size())));
354
+ }
355
+
356
+ template<class CharT>
357
+ inline bool operator>(const BasicStringPiece<CharT>& x,
358
+ const BasicStringPiece<CharT>& y) {
359
+ return y < x;
360
+ }
361
+
362
+ template<class CharT>
363
+ inline bool operator<=(const BasicStringPiece<CharT>& x,
364
+ const BasicStringPiece<CharT>& y) {
365
+ return !(x > y);
366
+ }
367
+
368
+ template<class CharT>
369
+ inline bool operator>=(const BasicStringPiece<CharT>& x,
370
+ const BasicStringPiece<CharT>& y) {
371
+ return !(x < y);
372
+ }
373
+
374
+ // allow StringPiece to be logged (needed for unit testing).
375
+ template<class CharT>
376
+ std::ostream& operator<<(std::ostream& o,
377
+ const BasicStringPiece<CharT>& piece) {
378
+ o.write(piece.data(), static_cast<std::streamsize>(piece.size()));
379
+ return o;
380
+ }
381
+
382
+ typedef BasicStringPiece<char, std::char_traits<char> > StringPiece;
383
+
384
+ } } // namespace iv::core
385
+ #endif // IV_STRINGPIECE_H_