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 #include <boost/cstdint.hpp>
00020 #include <boost/operators.hpp>
00021 #include <boost/static_assert.hpp>
00022 #include <boost/utility.hpp>
00023
00024 #include <adobe/cstring.hpp>
00025 #include <adobe/string_fwd.hpp>
00026 #include <adobe/typeinfo.hpp>
00027 #include <adobe/vector.hpp>
00028
00029
00030
00031 namespace std {
00032
00033
00034
00042
00043 template<typename CharT, class Traits, class Allocator>
00044 typename std::basic_string<CharT, Traits, Allocator>&
00045 operator << ( std::basic_string<CharT, Traits, Allocator>& out,
00046 const std::basic_string<CharT, Traits, Allocator>& in)
00047 {
00048 typename std::basic_string<CharT, Traits, Allocator>::size_type required(in.size() + out.size());
00049
00050 if (required > out.capacity()) out.reserve((std::max)(out.capacity() * 2, required));
00051
00052 out += in;
00053 return out;
00054 }
00055
00056
00057
00059 template<typename CharT, class Traits, class Allocator>
00060 typename std::basic_string<CharT, Traits, Allocator>&
00061 operator << (std::basic_string<CharT, Traits, Allocator>& out_str, const CharT* in_str)
00062 {
00063 typename std::basic_string<CharT, Traits, Allocator>::size_type required(std::strlen(in_str) + out_str.size());
00064
00065 if (required > out_str.capacity()) out_str.reserve((std::max)(out_str.capacity() * 2, required));
00066
00067 out_str += in_str;
00068 return out_str;
00069 }
00070
00072
00073
00074
00075 }
00076
00077
00078
00079 namespace adobe {
00080
00081
00082
00121 inline std::string make_string(const char* a, const char * b)
00122 {
00123 std::string result;
00124 result.reserve(std::strlen(a) + std::strlen(b));
00125 result += a;
00126 result += b;
00127 return result;
00128 }
00129
00130
00131
00132 inline std::string make_string(const char* a, const char * b, const char* c)
00133 {
00134 std::string result;
00135 result.reserve(std::strlen(a) + std::strlen(b) + std::strlen(b));
00136 result += a;
00137 result += b;
00138 result += c;
00139 return result;
00140 }
00141
00143
00144
00145
00147 struct str_less_t : std::binary_function<const char*, const char*, bool>
00148 {
00149 bool operator()(const char* x, const char* y) const
00150 { return adobe::strcmp(x, y) < 0; }
00151 };
00152
00153
00154
00155
00156
00157 }
00158
00159
00160
00161 namespace adobe {
00162 namespace version_1 {
00163
00168
00169
00170
00172 template <typename Derived>
00173 class empty_base_t { };
00174
00175
00176
00188 class string_t : boost::totally_ordered<string_t, string_t, empty_base_t<string_t> >
00189 {
00190 public:
00191 typedef char value_type;
00192 typedef char* pointer;
00193 typedef const char* const_pointer;
00194 typedef char& reference;
00195 typedef const char& const_reference;
00196 typedef std::size_t size_type;
00197 typedef std::ptrdiff_t difference_type;
00198 typedef char* iterator;
00199 typedef const char* const_iterator;
00200 typedef std::reverse_iterator<char*> reverse_iterator;
00201 typedef std::reverse_iterator<const char*> const_reverse_iterator;
00202
00203 private:
00204 typedef vector<value_type> storage_type;
00205
00206 storage_type storage_m;
00207
00208
00209
00210
00211
00212
00213 template <typename ForwardIterator>
00214 void assign(ForwardIterator first, ForwardIterator last, std::forward_iterator_tag)
00215 {
00216 storage_type tmp;
00217 if (first != last)
00218 {
00219 const size_type len(std::distance(first, last));
00220 tmp.reserve(len + 1);
00221 tmp.insert(tmp.end(), first, last);
00222 tmp.push_back(char(0));
00223 }
00224 storage_m.swap(tmp);
00225 }
00226
00227 template <typename InputIterator>
00228 void assign(InputIterator first, InputIterator last, std::input_iterator_tag)
00229 {
00230 storage_type tmp;
00231 if (first != last)
00232 {
00233 tmp.insert(tmp.end(), first, last);
00234 tmp.push_back(char(0));
00235 }
00236 storage_m.swap(tmp);
00237 }
00238
00239 template <typename Iterator>
00240 void assign(Iterator first, Iterator last)
00241 {
00242 assign(first, last,
00243 typename std::iterator_traits<Iterator>::iterator_category());
00244 }
00245
00246 public:
00250 string_t() { }
00251
00255 string_t(const string_t& s) : storage_m(s.storage_m) { }
00256
00260 string_t(move_from<string_t> x) : storage_m(move(x.source.storage_m)) { }
00261
00267 string_t(const char* s);
00268
00275 string_t(const char* s, std::size_t length);
00276
00283 template <typename Iterator>
00284 string_t(Iterator first, Iterator last)
00285 { assign(first, last); }
00286
00292 string_t(const std::string& s);
00293
00297 ~string_t() { }
00298
00303 string_t& operator=(string_t s) { storage_m = move(s.storage_m); return *this; }
00304
00308
00309
00310
00311
00312
00313
00314 operator std::string() const
00315 { return std::string(begin(), end()); }
00316
00321 const char* c_str() const
00322 { return empty() ? "" : &storage_m[0]; }
00323
00327 void push_back(value_type c);
00328
00332 template <typename Iterator>
00333 void append(Iterator first, Iterator last)
00334 {
00335 if (first != last)
00336 {
00337 if (!storage_m.empty())
00338 storage_m.pop_back();
00339
00340 storage_m.insert(storage_m.end(), first, last);
00341 storage_m.push_back(0);
00342 }
00343 }
00344
00348 void append(const string_t& s)
00349 { append(s.begin(), s.end()); }
00350
00354 void append(const char* s)
00355 { append(s, s + std::strlen(s)); }
00356
00360 void append(const char* s, std::size_t length)
00361 { append(s, s + length); }
00362
00366 void append(const std::string& s)
00367 { append(s.begin(), s.end()); }
00368
00372 string_t& operator+=(const string_t& s)
00373 { append(s); return *this; }
00374
00378 string_t& operator+=(const char* s)
00379 { append(s); return *this; }
00380
00384 string_t& operator+=(const std::string& s)
00385 { append(s); return *this; }
00386
00390 const_iterator begin() const
00391 { return storage_m.begin(); }
00392
00396 const_iterator end() const
00397 { return storage_m.empty() ? storage_m.end() : boost::prior(storage_m.end()); }
00398
00402 const_reverse_iterator rbegin() const
00403 { return const_reverse_iterator(end()); }
00404
00408 const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
00409
00414 size_type capacity() const;
00415
00421 void reserve(size_type n)
00422 { storage_m.reserve(0 == n ? 0 : n + 1); }
00423
00427 void clear()
00428 { storage_m.clear(); }
00429
00433 size_type size() const
00434 { return storage_m.empty() ? 0 : storage_m.size() - 1; }
00435
00439 bool empty() const
00440 { return storage_m.empty(); }
00441
00445 void swap(string_t& s)
00446 { storage_m.swap(s.storage_m); }
00447
00448 friend bool operator==(const string_t& x, const string_t& y)
00449 {
00450 return x.storage_m == y.storage_m;
00451 }
00452
00453 friend bool operator<(const string_t& x, const string_t& y)
00454 {
00455 return x.storage_m < y.storage_m;
00456 }
00457
00458 friend inline void swap(string_t& x, string_t& y)
00459 { x.storage_m.swap(y.storage_m); }
00460 };
00461
00467 inline string_t operator+(string_t s1, const string_t& s2) { return move(s1 += s2); }
00468 inline string_t operator+(string_t s1, const std::string& s2) { return move(s1 += s2); }
00469 inline string_t operator+(string_t s1, const char* s2) { return move(s1 += s2); }
00470
00471
00472
00473 #if defined(ADOBE_STD_SERIALIZATION)
00474 inline std::ostream& operator << (std::ostream& os, const string_t& t)
00475 { return os << t.c_str(); }
00476 #endif
00477
00478
00479
00490 class string16_t : boost::totally_ordered<string16_t, string16_t, empty_base_t<string16_t> >
00491 {
00492 public:
00493 typedef boost::uint16_t value_type;
00494 typedef boost::uint16_t* pointer;
00495 typedef const boost::uint16_t* const_pointer;
00496 typedef boost::uint16_t& reference;
00497 typedef const boost::uint16_t& const_reference;
00498 typedef std::size_t size_type;
00499 typedef std::ptrdiff_t difference_type;
00500 typedef boost::uint16_t* iterator;
00501 typedef const boost::uint16_t* const_iterator;
00502 typedef std::reverse_iterator<boost::uint16_t*> reverse_iterator;
00503 typedef std::reverse_iterator<const boost::uint16_t*> const_reverse_iterator;
00504
00505 private:
00506 typedef vector<value_type> storage_type;
00507
00508 storage_type storage_m;
00509
00510
00511
00512
00513
00514
00515 template <typename ForwardIterator>
00516 void assign(ForwardIterator first, ForwardIterator last, std::forward_iterator_tag)
00517 {
00518 storage_type tmp;
00519 if (first != last)
00520 {
00521 const size_type len(std::distance(first, last));
00522 tmp.reserve(len + 1);
00523 tmp.insert(tmp.end(), first, last);
00524 tmp.push_back(boost::uint16_t(0));
00525 }
00526 storage_m.swap(tmp);
00527 }
00528
00529 template <typename InputIterator>
00530 void assign(InputIterator first, InputIterator last, std::input_iterator_tag)
00531 {
00532 storage_type tmp;
00533 if (first != last)
00534 {
00535 tmp.insert(tmp.end(), first, last);
00536 tmp.push_back(boost::uint16_t(0));
00537 }
00538 storage_m.swap(tmp);
00539 }
00540
00541 template <typename Iterator>
00542 void assign(Iterator first, Iterator last)
00543 {
00544 assign(first, last,
00545 typename std::iterator_traits<Iterator>::iterator_category());
00546 }
00547
00548 public:
00552 string16_t() { }
00553
00557 string16_t(const string16_t& s) : storage_m(s.storage_m) { }
00558
00562 string16_t(move_from<string16_t> x) : storage_m(move(x.source.storage_m)) { }
00563
00569 string16_t(const boost::uint16_t* s);
00570
00577 string16_t(const boost::uint16_t* s, std::size_t length);
00578
00585 template <typename Iterator>
00586 string16_t(Iterator first, Iterator last)
00587 { assign(first, last); }
00588
00592 ~string16_t() { }
00593
00597 string16_t& operator=(string16_t s)
00598 { storage_m = move(s.storage_m); return *this; }
00599
00604 const boost::uint16_t* c_str() const;
00605
00609 void push_back(value_type c);
00610
00614 template <typename Iterator>
00615 void append(Iterator first, Iterator last)
00616 {
00617 if (first != last)
00618 {
00619 if (!storage_m.empty())
00620 storage_m.pop_back();
00621
00622 storage_m.insert(storage_m.end(), first, last);
00623 storage_m.push_back(0);
00624 }
00625 }
00626
00630 void append(const string16_t& s)
00631 { append(s.begin(), s.end()); }
00632
00636 void append(const boost::uint16_t* s);
00637
00641 void append(const boost::uint16_t* s, std::size_t length)
00642 { append(s, s + length); }
00643
00647 string16_t& operator+=(const string16_t& s)
00648 { append(s); return *this; }
00649
00653 string16_t& operator+=(const boost::uint16_t* s)
00654 { append(s); return *this; }
00655
00659 const_iterator begin() const
00660 { return storage_m.begin(); }
00661
00665 const_iterator end() const
00666 { return storage_m.empty() ? storage_m.end() : boost::prior(storage_m.end()); }
00667
00671 const_reverse_iterator rbegin() const
00672 { return const_reverse_iterator(end()); }
00673
00677 const_reverse_iterator rend() const
00678 { return const_reverse_iterator(begin()); }
00679
00684 size_type capacity() const;
00685
00691 void reserve(size_type n)
00692 { storage_m.reserve(0 == n ? 0 : n + 1); }
00693
00697 void clear()
00698 { storage_m.clear(); }
00699
00703 size_type size() const
00704 { return storage_m.empty() ? 0 : storage_m.size() - 1; }
00705
00709 bool empty() const
00710 { return storage_m.empty(); }
00711
00715 void swap(string16_t& s)
00716 { storage_m.swap(s.storage_m); }
00717
00718 friend bool operator==(const string16_t& x, const string16_t& y)
00719 {
00720 return x.storage_m == y.storage_m;
00721 }
00722
00723 friend bool operator<(const string16_t& x, const string16_t& y)
00724 {
00725 return x.storage_m < y.storage_m;
00726 }
00727
00728 friend inline void swap(string16_t& x, string16_t& y) { x.storage_m.swap(y.storage_m); }
00729 };
00730
00737 inline string16_t operator+(string16_t s1, const string16_t& s2) { return move(s1 += s2); }
00738 inline string16_t operator+(string16_t s1, const boost::uint16_t* s2) { return move(s1 += s2); }
00739
00741
00742
00743
00744 BOOST_STATIC_ASSERT(sizeof(string_t) == sizeof(vector<char>));
00745 BOOST_STATIC_ASSERT(sizeof(string16_t) == sizeof(vector<boost::uint16_t>));
00746
00747
00748
00749 }
00750
00751
00752
00753 using version_1::string_t;
00754 using version_1::string16_t;
00755
00756
00757
00758 }
00759
00760
00761
00762 ADOBE_NAME_TYPE_0("string_t:version_1:adobe", adobe::version_1::string_t)
00763 ADOBE_NAME_TYPE_0("string16_t:version_1:adobe", adobe::version_1::string16_t)
00764
00765 ADOBE_SHORT_NAME_TYPE('s','t','r','g', adobe::version_1::string_t)
00766 ADOBE_SHORT_NAME_TYPE('s','t','1','6', adobe::version_1::string16_t)
00767
00768
00769
00770 namespace boost {
00771
00772 template <>
00773 struct has_nothrow_constructor<adobe::version_1::string_t> : boost::mpl::true_ { };
00774
00775 template <>
00776 struct has_nothrow_constructor<adobe::version_1::string16_t> : boost::mpl::true_ { };
00777
00778 }
00779
00780
00781
00782 #endif
00783
00784