diff options
| author | jacqueline <me@jacqueline.id.au> | 2023-06-23 15:31:45 +1000 |
|---|---|---|
| committer | jacqueline <me@jacqueline.id.au> | 2023-06-23 15:31:45 +1000 |
| commit | aee0474191aa6b4e4505e3f5a74b4ac8cc48063b (patch) | |
| tree | f899ca369fa64975dc4c8f6d005d7aa1842045cd /lib/shared_string/include/shared_string.h | |
| parent | cde8002df4a86a2a6efd4aa0b5c174b2f39f7bf7 (diff) | |
| download | tangara-fw-aee0474191aa6b4e4505e3f5a74b4ac8cc48063b.tar.gz | |
Add a shared string library
Diffstat (limited to 'lib/shared_string/include/shared_string.h')
| -rwxr-xr-x | lib/shared_string/include/shared_string.h | 586 |
1 files changed, 586 insertions, 0 deletions
diff --git a/lib/shared_string/include/shared_string.h b/lib/shared_string/include/shared_string.h new file mode 100755 index 00000000..f3cbc7ca --- /dev/null +++ b/lib/shared_string/include/shared_string.h @@ -0,0 +1,586 @@ +#pragma once + +#ifndef _SHARED_STRING_H_INCLUDED_ +#define _SHARED_STRING_H_INCLUDED_ + +/** + * basic_shared_string + * + * Copyright (c) 2015 Scott Schanel http://github.com/sschanel/shared_string + * + * License: MIT License + * + * Uses std::shared_ptr internally to keep memory allocation to a minimum. + * This is a boost-less implementation that does not use boost::flyweights. + * That means that if you try hard enough you can outsmart it and do + * things very ineffeciently. + * + * But! If you embrace it, you get all the same methods that basic_string + * has (as of C++11), and you get a true shared string and it's thread-safe. + * Missing methods from basic_string: reserve(), capacity(), shrink_to_fit(). + * append(), assign(), insert(), erase(), replace(), push_front(), push_back(), + * all methods that return a non-const iterator. Almost all of the implemented + * methods are thin wrappers around the shared string. + * + * If you need those methods, make a copy of the internal string by calling + * str() and work on that temporary string. + * + * You still get operator=(). And clear(). + * + * + * + */ + +#include <string> +#include <memory> +#include <functional> + +template <typename CharT, + class Traits = std::char_traits<CharT>, + class Allocator = std::allocator < CharT > +> +class basic_shared_string { + +public: + typedef std::basic_string<CharT, Traits, Allocator> string_type; + + typedef typename string_type::const_iterator const_iterator; + typedef typename string_type::const_reverse_iterator const_reverse_iterator; + typedef typename string_type::size_type size_type; + +private: + std::shared_ptr<const string_type> string_; + + void replace_contents(string_type&& newString) { + string_ = std::make_shared<const string_type>(std::move(newString)); + } + +public: + static const size_type npos = (size_t)-1; + + const string_type& str() const { + static const string_type empty; + if (string_.get() != nullptr) { + return *(string_.get()); + } + return empty; + } + + operator const string_type&() { + return str(); + } + + basic_shared_string() { + } + + basic_shared_string(const CharT * s) { + replace_contents(string_type(s)); + } + + basic_shared_string(const string_type& s) { + replace_contents(string_type(s)); + } + + basic_shared_string(string_type&& s) { + replace_contents(std::move(s)); + } + + basic_shared_string(const basic_shared_string& s) { + string_ = s.string_; + } + + void clear() { + string_ = nullptr; + } + + basic_shared_string& operator=(const basic_shared_string& s) { + string_ = s.string_; + return *this; + } + + basic_shared_string& operator=(const string_type& str) { + replace_contents(string_type(str)); + return *this; + } + + basic_shared_string& operator=(string_type&& str) { + replace_contents(std::move(str)); + return *this; + } + + basic_shared_string& operator=(const CharT* s) { + replace_contents(string_type(s)); + return *this; + } + + basic_shared_string& operator=(CharT ch) { + replace_contents(string_type(ch)); + return *this; + } + + basic_shared_string& operator=(std::initializer_list<CharT> ilist) { + replace_contents(string_type(ilist)); + return *this; + } + + void swap(basic_shared_string& rhs) { + this->string_.swap(rhs.string_); + } + + + CharT at(size_type pos) const { + return str().at(pos); + } + + CharT operator[](size_type pos) const { + return str()[pos]; + } + + CharT front() const { + return str().front(); + } + + CharT back() const { + return str().back(); + } + + const CharT * c_str() const { + return str().c_str(); + } + + const_iterator begin() const { + return str().begin(); + } + + const_iterator cbegin() const { + return str().cbegin(); + } + + const_iterator end() const { + return str().end(); + } + + const_iterator cend() const { + return str().end(); + } + + const_reverse_iterator rbegin() const { + return str().rbegin(); + } + + const_reverse_iterator crbegin() const { + return str().crbegin(); + } + + const_reverse_iterator rend() const { + return str().rend(); + } + + const_reverse_iterator crend() const { + return str().crend(); + } + + + + bool empty() const { + return str().empty(); + } + + size_t size() const { + return str().size(); + } + + size_t length() const { + return str().length(); + } + + size_t max_size() const { + return str().max_size(); + } + + size_t capacity() const { + return str().capacity(); + } + + int compare(const string_type& rhs) const { + return str().compare(rhs); + } + + int compare(const basic_shared_string& rhs) const { + return str().compare(rhs.str()); + } + + int compare(size_type pos1, size_type count1, + const string_type& str) const { + return str().compare(pos1, count1, str); + } + + int compare(const CharT* s) const { + return str().compare(s); + } + + int compare(size_type pos1, size_type count1, + const CharT* s) const { + + return str().compare(pos1, count1, s); + } + + int compare( + size_type pos1, + size_type count1, + const CharT* s, + size_type count2) const { + + return str().compare(pos1, count1, s, count2); + } + + basic_shared_string<CharT> substr( + size_type pos = 0, + size_type count = npos) const { + + if (pos == 0) { + if (count == npos) { + return *this; + } + else if (count >= str().size()) { + return *this; + } + } + return basic_shared_string(str().substr(pos, count)); + } + + size_type copy( + CharT* dest, + size_type count, + size_type pos = 0) const { + return str().copy(dest, count, pos); + } + + size_type find(const string_type& str, size_type pos = 0) const { + return str().find(str, pos); + } + + size_type find(const CharT* s, size_type pos, size_type count) const { + return str().find(s, pos, count); + } + + size_type find(const CharT* s, size_type pos = 0) const { + return str().find(s, pos); + } + + size_type find(CharT ch, size_type pos = 0) const { + return str().find(ch, pos); + } + + size_type rfind(const string_type& str, size_type pos = npos) const { + return str().rfind(str, pos); + } + + size_type rfind(const CharT* s, size_type pos, size_type count) const { + return str().rfind(s, pos, count); + } + + size_type rfind(const CharT* s, size_type pos = npos) const { + return str().rfind(s, pos); + } + + size_type rfind(CharT ch, size_type pos = npos) const { + return str().rfind(ch, pos); + } + + size_type find_first_of(const string_type& str, size_type pos = 0) const { + return str().find_first_of(str, pos); + } + + size_type find_first_of(const CharT* s, size_type pos, size_type count) const { + return str().find_first_of(s, pos, count); + } + + size_type find_first_of(const CharT* s, size_type pos = 0) const { + return str().find_first_of(s, pos); + } + + size_type find_first_of(CharT ch, size_type pos = 0) const { + return str().find_first_of(ch, pos); + } + + size_type find_first_not_of(const string_type& str, size_type pos = 0) const { + return str().find_first_not_of(str, pos); + } + + size_type find_first_not_of(const CharT* s, size_type pos, size_type count) const { + return str().find_first_not_of(s, pos, count); + } + + size_type find_first_not_of(const CharT* s, size_type pos = 0) const { + return str().find_first_not_of(s, pos); + } + + size_type find_first_not_of(CharT ch, size_type pos = 0) const { + return str().find_first_not_of(ch, pos); + } + + size_type find_last_of(const string_type& str, size_type pos = npos) const { + return str().find_last_of(str, pos); + } + + size_type find_last_of(const CharT* s, size_type pos, size_type count) const { + return str().find_last_of(s, pos, count); + } + + size_type find_last_of(const CharT* s, size_type pos = npos) const { + return str().find_last_of(s, pos); + } + size_type find_last_of(CharT ch, size_type pos = npos) const { + return str().find_last_of(ch, pos); + } + size_type find_last_not_of(const string_type& str, size_type pos = npos) const { + return str().find_last_not_of(str, pos); + } + size_type find_last_not_of(const CharT* s, size_type pos, size_type count) const { + return str().find_last_not_of(s, pos, count); + } + size_type find_last_not_of(const CharT* s, size_type pos = npos) const { + return str().find_last_not_of(s, pos); + } + size_type find_last_not_of(CharT ch, size_type pos = npos) const { + return str().find_last_not_of(ch, pos); + } +}; + +template< class CharT, class Traits, class Alloc > +bool operator==( + const basic_shared_string<CharT, Traits, Alloc>& lhs, + const basic_shared_string<CharT, Traits, Alloc>& rhs) { + return lhs.str() == rhs.str(); +} + +template< class CharT, class Traits, class Alloc > +bool operator!=( + const basic_shared_string<CharT, Traits, Alloc>& lhs, + const basic_shared_string<CharT, Traits, Alloc>& rhs) { + return lhs.str() != rhs.str(); +} + +template< class CharT, class Traits, class Alloc > +bool operator<( + const basic_shared_string<CharT, Traits, Alloc>& lhs, + const basic_shared_string<CharT, Traits, Alloc>& rhs) { + return lhs.str() < rhs.str(); +} + +template< class CharT, class Traits, class Alloc > +bool operator<=( + const basic_shared_string<CharT, Traits, Alloc>& lhs, + const basic_shared_string<CharT, Traits, Alloc>& rhs) { + return lhs.str() <= rhs.str(); +} + +template< class CharT, class Traits, class Alloc > +bool operator>( + const basic_shared_string<CharT, Traits, Alloc>& lhs, + const basic_shared_string<CharT, Traits, Alloc>& rhs) { + + return lhs.str() > rhs.str(); +} + +template< class CharT, class Traits, class Alloc > +bool operator>=( + const basic_shared_string<CharT, Traits, Alloc>& lhs, + const basic_shared_string<CharT, Traits, Alloc>& rhs) { + + return lhs.str() >= rhs.str(); +} + +template< class CharT, class Traits, class Alloc > +bool operator==( + const CharT* lhs, + const basic_shared_string<CharT, Traits, Alloc>& rhs) { + return operator==(lhs, rhs.str()); +} + +template< class CharT, class Traits, class Alloc > +bool operator==( + const basic_shared_string<CharT, Traits, Alloc>& lhs, + const CharT* rhs) { + + return operator==(lhs.str(), rhs); +} + +template< class CharT, class Traits, class Alloc > +bool operator!=(const CharT* lhs, const basic_shared_string<CharT, Traits, Alloc>& rhs) { + return operator!=(lhs, rhs.str()); +} + +template< class CharT, class Traits, class Alloc > +bool operator!=(const basic_shared_string<CharT, Traits, Alloc>& lhs, const CharT* rhs) { + return operator!=(lhs.str(), rhs); +} + +template< class CharT, class Traits, class Alloc > +bool operator<(const CharT* lhs, const basic_shared_string<CharT, Traits, Alloc>& rhs) { + return operator<(lhs, rhs.str()); +} + +template< class CharT, class Traits, class Alloc > +bool operator<(const basic_shared_string<CharT, Traits, Alloc>& lhs, const CharT* rhs) { + return operator<(lhs.str(), rhs); +} + +template< class CharT, class Traits, class Alloc > +bool operator<=(const CharT* lhs, const basic_shared_string<CharT, Traits, Alloc>& rhs) { + return operator<=(lhs, rhs.str()); +} + +template< class CharT, class Traits, class Alloc > +bool operator<=(const basic_shared_string<CharT, Traits, Alloc>& lhs, const CharT* rhs) { + return operator<=(lhs.str(), rhs); +} + +template< class CharT, class Traits, class Alloc > +bool operator>(const CharT* lhs, const basic_shared_string<CharT, Traits, Alloc>& rhs) { + return operator>(lhs, rhs.str()); +} + +template< class CharT, class Traits, class Alloc > +bool operator>(const basic_shared_string<CharT, Traits, Alloc>& lhs, const CharT* rhs) { + return operator>(lhs.str(), rhs); +} + +template< class CharT, class Traits, class Alloc > +bool operator>=(const CharT* lhs, const basic_shared_string<CharT, Traits, Alloc>& rhs) { + return operator>=(lhs, rhs.str()); +} + +template< class CharT, class Traits, class Alloc > +bool operator>=(const basic_shared_string<CharT, Traits, Alloc>& lhs, const CharT* rhs) { + return operator>=(lhs.str(), rhs); +} + + +template <class CharT, class Traits, class Allocator> +std::basic_ostream<CharT, Traits>& operator<<( + std::basic_ostream<CharT, Traits>& os, + const basic_shared_string<CharT, Traits, Allocator>& str) { + return operator<<(os, str.str()); +} + +template <class CharT, class Traits, class Allocator> +std::basic_istream<CharT, Traits>& operator>>( + std::basic_istream<CharT, Traits>& is, + basic_shared_string<CharT, Traits, Allocator>& str) { + + std::basic_string<CharT, Traits, Allocator> temp; + operator>>(is, temp); + str = temp; + return is; +} + +template< class CharT, class Traits, class Alloc > +basic_shared_string<CharT, Traits, Alloc> operator+( + const basic_shared_string<CharT, Traits, Alloc>& lhs, + const basic_shared_string<CharT, Traits, Alloc>& rhs) { + return basic_shared_string<CharT, Traits, Alloc>(operator+(lhs.str(), rhs.str())); +} + +template< class CharT, class Traits, class Alloc > +basic_shared_string<CharT, Traits, Alloc> operator+( + const basic_shared_string<CharT, Traits, Alloc>& lhs, + const std::basic_string<CharT, Traits, Alloc>& rhs) { + return basic_shared_string<CharT, Traits, Alloc>(operator+(lhs.str(), rhs)); +} + +template< class CharT, class Traits, class Alloc > +basic_shared_string<CharT, Traits, Alloc> operator+( + const std::basic_string<CharT, Traits, Alloc>& lhs, + const basic_shared_string<CharT, Traits, Alloc>& rhs) { + return basic_shared_string<CharT, Traits, Alloc>(operator+(lhs, rhs.str())); +} + +template< class CharT, class Traits, class Alloc > +basic_shared_string<CharT, Traits, Alloc> operator+( + const CharT* lhs, + const basic_shared_string<CharT, Traits, Alloc>& rhs) { + + return basic_shared_string<CharT, Traits, Alloc>(operator+(lhs, rhs.str())); +} + +template< class CharT, class Traits, class Alloc > +basic_shared_string<CharT, Traits, Alloc> operator+( + CharT lhs, + const basic_shared_string<CharT, Traits, Alloc>& rhs) { + + return basic_shared_string<CharT, Traits, Alloc>(operator+(lhs, rhs.str())); +} + +template< class CharT, class Traits, class Alloc > +basic_shared_string<CharT, Traits, Alloc> operator+( + const basic_shared_string<CharT, Traits, Alloc>& lhs, + const CharT* rhs) { + + return basic_shared_string<CharT, Traits, Alloc>(operator+(lhs.str(), rhs)); +} + +template<class CharT, class Traits, class Alloc> +basic_shared_string<CharT, Traits, Alloc> operator+( + const basic_shared_string<CharT, Traits, Alloc>& lhs, + CharT rhs) { + + return basic_shared_string<CharT, Traits, Alloc>(operator+(lhs.str(), rhs)); +} + +namespace std { + + template <class CharT, class Traits, class Alloc> + int stoi(const basic_shared_string<CharT, Traits, Alloc>& str, std::size_t* pos = 0, int base = 10) { + return stoi(str.str(), pos, base); + } + + template <class CharT, class Traits, class Alloc> + long stol(const basic_shared_string<CharT, Traits, Alloc>& str, std::size_t* pos = 0, int base = 10) { + return stol(str.str(), pos, base); + } + + template <class CharT, class Traits, class Alloc> + long long stoll(const basic_shared_string<CharT, Traits, Alloc>& str, std::size_t* pos = 0, int base = 10) { + return stoll(str.str(), pos, base); + } + + template <class CharT, class Traits, class Alloc> + unsigned long stoul(const basic_shared_string<CharT, Traits, Alloc>& str, std::size_t* pos = 0, int base = 10) { + return stoul(str.str(), pos, base); + } + + template <class CharT, class Traits, class Alloc> + unsigned long long stoull(const basic_shared_string<CharT, Traits, Alloc>& str, std::size_t* pos = 0, int base = 10) { + return stoull(str.str(), pos, base); + } + + template <class CharT, class Traits, class Alloc> + float stof(const basic_shared_string<CharT, Traits, Alloc>& str, std::size_t* pos = 0) { + return stof(str.str(), pos); + } + + template <class CharT, class Traits, class Alloc> + double stod(const basic_shared_string<CharT, Traits, Alloc>& str, std::size_t* pos = 0) { + return stod(str.str(), pos); + } + + template <class CharT, class Traits, class Alloc> + double stold(const basic_shared_string<CharT, Traits, Alloc>& str, std::size_t* pos = 0) { + return stold(str.str(), pos); + } + + template <class CharT> + struct hash < basic_shared_string<CharT> > { + size_t operator()(const basic_shared_string<CharT>& key) { + return hash<std::string>()(key.str()); + } + }; +} + +typedef basic_shared_string<char> shared_string; +typedef basic_shared_string<wchar_t> shared_wstring; + + +#endif // _STRING_REF_H_INCLUDED_ |
