Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <algorithm>
- #include <type_traits>
- #include <memory>
- #include <cassert>
- enum class Place {inInitializedReadonlyArea, inHeapArea};
- template <typename Type, Place Where>
- class ImmutableString;
- template <typename Type>
- class ImmutableString<Type, Place::inInitializedReadonlyArea>
- {
- static_assert(std::is_same<Type, char>::value || std::is_same<Type, wchar_t>::value, "The type you've given is currently unsupported");
- public: // Should be privated, bug because of an error...
- ImmutableString(const Type* const str_, const size_t len_): str(str_), len(len_) {}
- private:
- ImmutableString() = delete;
- void operator delete(void *) = delete;
- void* operator new(size_t) = delete;
- public:
- size_t getLength() const
- {
- return len;
- }
- Type operator [](size_t index) const
- {
- assert(index < len);
- return str[index];
- }
- ImmutableString<Type, Place::inInitializedReadonlyArea> substr(size_t pos = 0, size_t n = npos) const
- {
- assert(pos < len);
- ImmutableString<Type, Place::inInitializedReadonlyArea> result(*this);
- result.str += pos;
- result.len = (n > len || n + pos > len) ? len - pos : n;
- return result;
- }
- friend std::basic_ostream<Type>& operator <<(std::basic_ostream<Type>& os, const ImmutableString<Type, Place::inInitializedReadonlyArea>& rhs)
- {
- std::copy_n(rhs.str, rhs.len, std::ostreambuf_iterator<Type>(os));
- return os;
- }
- //invalid argument list; is it a bug of g++ 4.7?
- //friend ImmutableString<char, Place::Instack> operator "" _ImmStr(const char*, size_t);
- template <typename T, Place W> friend
- ImmutableString<T, Place::inHeapArea> operator +(const ImmutableString<T, W>& str1, const ImmutableString<T, W>& str2);
- public:
- static const size_t npos = size_t(-1);
- private:
- const Type* str;
- size_t len;
- };
- ImmutableString<char, Place::inInitializedReadonlyArea> operator "" _ImmStr(const char* str_, size_t len_)
- {
- return ImmutableString<char, Place::inInitializedReadonlyArea>(str_, len_);
- }
- ImmutableString<wchar_t, Place::inInitializedReadonlyArea> operator "" _ImmStr(const wchar_t* str_, size_t len_)
- {
- return ImmutableString<wchar_t, Place::inInitializedReadonlyArea>(str_, len_);
- }
- template <typename Type>
- class ImmutableString<Type, Place::inHeapArea>
- {
- static_assert(std::is_same<Type, char>::value || std::is_same<Type, wchar_t>::value, "The type you've given is currently unsupported");
- private:
- ImmutableString() = delete;
- ImmutableString(const size_t len_): srcStr(new Type[len_], [](Type* str){ delete[] str; }), str(srcStr.get()), len(len_) {}
- void operator delete(void *) = delete;
- void* operator new(size_t) = delete;
- public:
- size_t getLength() const
- {
- return len;
- }
- Type operator [](size_t index) const
- {
- assert(index < len);
- return str[index];
- }
- friend std::basic_ostream<Type>& operator <<(std::basic_ostream<Type>& os, const ImmutableString<Type, Place::inHeapArea>& rhs)
- {
- std::copy_n(rhs.str, rhs.len, std::ostreambuf_iterator<Type>(os));
- return os;
- }
- ImmutableString substr(size_t pos = 0, size_t n = npos) const
- {
- assert(pos < len);
- ImmutableString result(*this);
- result.str += pos;
- result.len = (n > len || n + pos > len) ? len - pos : n;
- return result;
- }
- template <typename T, Place W> friend
- ImmutableString<T, Place::inHeapArea> operator +(const ImmutableString<T, W>& str1, const ImmutableString<T, W>& str2);
- public:
- static const size_t npos = size_t(-1);
- private:
- std::shared_ptr<Type> srcStr;
- Type* str;
- size_t len;
- };
- template <typename Type, Place Where>
- ImmutableString<Type, Place::inHeapArea> operator +(const ImmutableString<Type, Where>& str1, const ImmutableString<Type, Where>& str2)
- {
- ImmutableString<Type, Place::inHeapArea> result(str1.len + str2.len);
- std::copy_n(&str1.str[0], str1.len, &result.str[0]);
- std::copy_n(&str2.str[0], str2.len, &result.str[str1.len]);
- return result;
- }
- int main()
- {
- using namespace std;
- cout << "1234567"_ImmStr.substr(3) << endl; // Don't need to allocate heap memory
- cout << std::string("1234567").substr(3) << endl; // May allocate heap memory twice;
- cout << ("1234567"_ImmStr + "abcdefg"_ImmStr).substr(3, 7) << endl; // Only allocate heap memory once (or twice >_<)
- cout << (std::string("1234567") += "abcdefg").substr(3, 7) << endl; // May allocate heap memory 3 times
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement