00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef ADOBE_STRING_HPP
00010 #define ADOBE_STRING_HPP
00011
00012 #include <adobe/config.hpp>
00013
00014 #include <cstring>
00015 #include <functional>
00016 #include <iterator>
00017 #include <string>
00018
00019 #if defined(ADOBE_STD_SERIALIZATION)
00020 #include <iosfwd>
00021 #endif
00022
00023 #include <boost/cstdint.hpp>
00024 #include <boost/operators.hpp>
00025 #include <boost/static_assert.hpp>
00026 #include <boost/utility.hpp>
00027
00028 #include <adobe/cstring.hpp>
00029 #include <adobe/string_fwd.hpp>
00030 #include <adobe/typeinfo.hpp>
00031 #include <adobe/vector.hpp>
00032
00033
00034
00035 namespace std {
00036
00037
00038
00046
00047 template<typename CharT, class Traits, class Allocator>
00048 typename std::basic_string<CharT, Traits, Allocator>&
00049 operator << ( std::basic_string<CharT, Traits, Allocator>& out,
00050 const std::basic_string<CharT, Traits, Allocator>& in)
00051 {
00052 typename std::basic_string<CharT, Traits, Allocator>::size_type required(in.size() + out.size());
00053
00054 if (required > out.capacity()) out.reserve((std::max)(out.capacity() * 2, required));
00055
00056 out += in;
00057 return out;
00058 }
00059
00060
00061
00063 template<typename CharT, class Traits, class Allocator>
00064 typename std::basic_string<CharT, Traits, Allocator>&
00065 operator << (std::basic_string<CharT, Traits, Allocator>& out_str, const CharT* in_str)
00066 {
00067 typename std::basic_string<CharT, Traits, Allocator>::size_type required(std::strlen(in_str) + out_str.size());
00068
00069 if (required > out_str.capacity()) out_str.reserve((std::max)(out_str.capacity() * 2, required));
00070
00071 out_str += in_str;
00072 return out_str;
00073 }
00074
00076
00077
00078
00079 }
00080
00081
00082
00083 namespace adobe {
00084
00085
00086
00125 inline std::string make_string(const char* a, const char * b)
00126 {
00127 std::string result;
00128 result.reserve(std::strlen(a) + std::strlen(b));
00129 result += a;
00130 result += b;
00131 return result;
00132 }
00133
00134
00135
00136 inline std::string make_string(const char* a, const char * b, const char* c)
00137 {
00138 std::string result;
00139 result.reserve(std::strlen(a) + std::strlen(b) + std::strlen(b));
00140 result += a;
00141 result += b;
00142 result += c;
00143 return result;
00144 }
00145
00147
00148
00149
00151 struct str_less_t : std::binary_function<const char*, const char*, bool>
00152 {
00153 bool operator()(const char* x, const char* y) const
00154 { return adobe::strcmp(x, y) < 0; }
00155 };
00156
00157
00158
00159
00160
00161 }
00162
00163
00164
00165 namespace adobe {
00166 namespace version_1 {
00167
00172
00173
00174
00176 template <typename Derived>
00177 class empty_base_t { };
00178
00179
00180
00192 class string_t : boost::totally_ordered<string_t, string_t, empty_base_t<string_t> >
00193 {
00194 public:
00195 typedef char value_type;
00196 typedef char* pointer;
00197 typedef const char* const_pointer;
00198 typedef char& reference;
00199 typedef const char& const_reference;
00200 typedef std::size_t size_type;
00201 typedef std::ptrdiff_t difference_type;
00202 typedef char* iterator;
00203 typedef const char* const_iterator;
00204 typedef std::reverse_iterator<char*> reverse_iterator;
00205 typedef std::reverse_iterator<const char*> const_reverse_iterator;
00206
00207 private:
00208 typedef vector<value_type> storage_type;
00209
00210 storage_type storage_m;
00211
00212
00213
00214
00215
00216
00217 template <typename ForwardIterator>
00218 void assign(ForwardIterator first, ForwardIterator last, std::forward_iterator_tag)
00219 {
00220 storage_type tmp;
00221 if (first != last)
00222 {
00223 const size_type len(std::distance(first, last));
00224 tmp.reserve(len + 1);
00225 tmp.insert(tmp.end(), first, last);
00226 tmp.push_back(char(0));
00227 }
00228 storage_m.swap(tmp);
00229 }
00230
00231 template <typename InputIterator>
00232 void assign(InputIterator first, InputIterator last, std::input_iterator_tag)
00233 {
00234 storage_type tmp;
00235 if (first != last)
00236 {
00237 tmp.insert(tmp.end(), first, last);
00238 tmp.push_back(char(0));
00239 }
00240 storage_m.swap(tmp);
00241 }
00242
00243 template <typename Iterator>
00244 void assign(Iterator first, Iterator last)
00245 {
00246 assign(first, last,
00247 typename std::iterator_traits<Iterator>::iterator_category());
00248 }
00249
00250 public:
00254 string_t() { }
00255
00259 string_t(const string_t& s) : storage_m(s.storage_m) { }
00260
00264 string_t(move_from<string_t> x) : storage_m(move(x.source.storage_m)) { }
00265
00271 string_t(const char* s);
00272
00279 string_t(const char* s, std::size_t length);
00280
00287 template <typename Iterator>
00288 string_t(Iterator first, Iterator last)
00289 { assign(first, last); }
00290
00296 string_t(const std::string& s);
00297
00301 ~string_t() { }
00302
00307 string_t& operator=(string_t s) { storage_m = move(s.storage_m); return *this; }
00308
00312
00313
00314
00315
00316
00317
00318 operator std::string() const
00319 { return std::string(begin(), end()); }
00320
00325 const char* c_str() const
00326 { return empty() ? "" : &storage_m[0]; }
00327
00331 void push_back(value_type c);
00332
00336 template <typename Iterator>
00337 void append(Iterator first, Iterator last)
00338 {
00339 if (first != last)
00340 {
00341 if (!storage_m.empty())
00342 storage_m.pop_back();
00343
00344 storage_m.insert(storage_m.end(), first, last);
00345 storage_m.push_back(0);
00346 }
00347 }
00348
00352 void append(const string_t& s)
00353 { append(s.begin(), s.end()); }
00354
00358 void append(const char* s)
00359 { append(s, s + std::strlen(s)); }
00360
00364 void append(const char* s, std::size_t length)
00365 { append(s, s + length); }
00366
00370 void append(const std::string& s)
00371 { append(s.begin(), s.end()); }
00372
00376 string_t& operator+=(const string_t& s)
00377 { append(s); return *this; }
00378
00382 string_t& operator+=(const char* s)
00383 { append(s); return *this; }
00384
00388 string_t& operator+=(const std::string& s)
00389 { append(s); return *this; }
00390
00394 const_iterator begin() const
00395 { return storage_m.begin(); }
00396
00400 const_iterator end() const
00401 { return storage_m.empty() ? storage_m.end() : boost::prior(storage_m.end()); }
00402
00406 const_reverse_iterator rbegin() const
00407 { return const_reverse_iterator(end()); }
00408
00412 const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
00413
00418 size_type capacity() const;
00419
00425 void reserve(size_type n)
00426 { storage_m.reserve(0 == n ? 0 : n + 1); }
00427
00431 void clear()
00432 { storage_m.clear(); }
00433
00437 size_type size() const
00438 { return storage_m.empty() ? 0 : storage_m.size() - 1; }
00439
00443 bool empty() const
00444 { return storage_m.empty(); }
00445
00449 void swap(string_t& s)
00450 { storage_m.swap(s.storage_m); }
00451
00452 friend bool operator==(const string_t& x, const string_t& y)
00453 {
00454 return x.storage_m == y.storage_m;
00455 }
00456
00457 friend bool operator<(const string_t& x, const string_t& y)
00458 {
00459 return x.storage_m < y.storage_m;
00460 }
00461
00462 friend inline void swap(string_t& x, string_t& y)
00463 { x.storage_m.swap(y.storage_m); }
00464 };
00465
00471 inline string_t operator+(string_t s1, const string_t& s2) { return move(s1 += s2); }
00472 inline string_t operator+(string_t s1, const std::string& s2) { return move(s1 += s2); }
00473 inline string_t operator+(string_t s1, const char* s2) { return move(s1 += s2); }
00474
00475
00476
00477 #if defined(ADOBE_STD_SERIALIZATION)
00478 std::ostream& operator<<(std::ostream& os, const string_t& t);
00479 #endif
00480
00481
00482
00493 class string16_t : boost::totally_ordered<string16_t, string16_t, empty_base_t<string16_t> >
00494 {
00495 public:
00496 typedef boost::uint16_t value_type;
00497 typedef boost::uint16_t* pointer;
00498 typedef const boost::uint16_t* const_pointer;
00499 typedef boost::uint16_t& reference;
00500 typedef const boost::uint16_t& const_reference;
00501 typedef std::size_t size_type;
00502 typedef std::ptrdiff_t difference_type;
00503 typedef boost::uint16_t* iterator;
00504 typedef const boost::uint16_t* const_iterator;
00505 typedef std::reverse_iterator<boost::uint16_t*> reverse_iterator;
00506 typedef std::reverse_iterator<const boost::uint16_t*> const_reverse_iterator;
00507
00508 private:
00509 typedef vector<value_type> storage_type;
00510
00511 storage_type storage_m;
00512
00513
00514
00515
00516
00517
00518 template <typename ForwardIterator>
00519 void assign(ForwardIterator first, ForwardIterator last, std::forward_iterator_tag)
00520 {
00521 storage_type tmp;
00522 if (first != last)
00523 {
00524 const size_type len(std::distance(first, last));
00525 tmp.reserve(len + 1);
00526 tmp.insert(tmp.end(), first, last);
00527 tmp.push_back(boost::uint16_t(0));
00528 }
00529 storage_m.swap(tmp);
00530 }
00531
00532 template <typename InputIterator>
00533 void assign(InputIterator first, InputIterator last, std::input_iterator_tag)
00534 {
00535 storage_type tmp;
00536 if (first != last)
00537 {
00538 tmp.insert(tmp.end(), first, last);
00539 tmp.push_back(boost::uint16_t(0));
00540 }
00541 storage_m.swap(tmp);
00542 }
00543
00544 template <typename Iterator>
00545 void assign(Iterator first, Iterator last)
00546 {
00547 assign(first, last,
00548 typename std::iterator_traits<Iterator>::iterator_category());
00549 }
00550
00551 public:
00555 string16_t() { }
00556
00560 string16_t(const string16_t& s) : storage_m(s.storage_m) { }
00561
00565 string16_t(move_from<string16_t> x) : storage_m(move(x.source.storage_m)) { }
00566
00572 string16_t(const boost::uint16_t* s);
00573
00580 string16_t(const boost::uint16_t* s, std::size_t length);
00581
00588 template <typename Iterator>
00589 string16_t(Iterator first, Iterator last)
00590 { assign(first, last); }
00591
00595 ~string16_t() { }
00596
00600 string16_t& operator=(string16_t s)
00601 { storage_m = move(s.storage_m); return *this; }
00602
00607 const boost::uint16_t* c_str() const;
00608
00612 void push_back(value_type c);
00613
00617 template <typename Iterator>
00618 void append(Iterator first, Iterator last)
00619 {
00620 if (first != last)
00621 {
00622 if (!storage_m.empty())
00623 storage_m.pop_back();
00624
00625 storage_m.insert(storage_m.end(), first, last);
00626 storage_m.push_back(0);
00627 }
00628 }
00629
00633 void append(const string16_t& s)
00634 { append(s.begin(), s.end()); }
00635
00639 void append(const boost::uint16_t* s);
00640
00644 void append(const boost::uint16_t* s, std::size_t length)
00645 { append(s, s + length); }
00646
00650 string16_t& operator+=(const string16_t& s)
00651 { append(s); return *this; }
00652
00656 string16_t& operator+=(const boost::uint16_t* s)
00657 { append(s); return *this; }
00658
00662 const_iterator begin() const
00663 { return storage_m.begin(); }
00664
00668 const_iterator end() const
00669 { return storage_m.empty() ? storage_m.end() : boost::prior(storage_m.end()); }
00670
00674 const_reverse_iterator rbegin() const
00675 { return const_reverse_iterator(end()); }
00676
00680 const_reverse_iterator rend() const
00681 { return const_reverse_iterator(begin()); }
00682
00687 size_type capacity() const;
00688
00694 void reserve(size_type n)
00695 { storage_m.reserve(0 == n ? 0 : n + 1); }
00696
00700 void clear()
00701 { storage_m.clear(); }
00702
00706 size_type size() const
00707 { return storage_m.empty() ? 0 : storage_m.size() - 1; }
00708
00712 bool empty() const
00713 { return storage_m.empty(); }
00714
00718 void swap(string16_t& s)
00719 { storage_m.swap(s.storage_m); }
00720
00721 friend bool operator==(const string16_t& x, const string16_t& y)
00722 {
00723 return x.storage_m == y.storage_m;
00724 }
00725
00726 friend bool operator<(const string16_t& x, const string16_t& y)
00727 {
00728 return x.storage_m < y.storage_m;
00729 }
00730
00731 friend inline void swap(string16_t& x, string16_t& y) { x.storage_m.swap(y.storage_m); }
00732 };
00733
00740 inline string16_t operator+(string16_t s1, const string16_t& s2) { return move(s1 += s2); }
00741 inline string16_t operator+(string16_t s1, const boost::uint16_t* s2) { return move(s1 += s2); }
00742
00744
00745
00746
00747 BOOST_STATIC_ASSERT(sizeof(string_t) == sizeof(vector<char>));
00748 BOOST_STATIC_ASSERT(sizeof(string16_t) == sizeof(vector<boost::uint16_t>));
00749
00750
00751
00752 }
00753
00754
00755
00756 using version_1::string_t;
00757 using version_1::string16_t;
00758
00759
00760
00761 }
00762
00763
00764
00765 ADOBE_NAME_TYPE_0("string_t:version_1:adobe", adobe::version_1::string_t)
00766 ADOBE_NAME_TYPE_0("string16_t:version_1:adobe", adobe::version_1::string16_t)
00767
00768 ADOBE_SHORT_NAME_TYPE('s','t','r','g', adobe::version_1::string_t)
00769 ADOBE_SHORT_NAME_TYPE('s','t','1','6', adobe::version_1::string16_t)
00770
00771
00772
00773 namespace boost {
00774
00775 template <>
00776 struct has_nothrow_constructor<adobe::version_1::string_t> : boost::mpl::true_ { };
00777
00778 template <>
00779 struct has_nothrow_constructor<adobe::version_1::string16_t> : boost::mpl::true_ { };
00780
00781 }
00782
00783
00784
00785 #endif
00786
00787