diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2020-01-21 20:25:43 +0000 |
---|---|---|
committer | Henning Baldersheim <balder@yahoo-inc.com> | 2020-01-21 20:25:43 +0000 |
commit | 4814eb34c725110f25ab4324699d6f17a291c116 (patch) | |
tree | 9b0402cb1f14a8b9826f744e9f7b491e4f4d1c45 /vespalib | |
parent | c9db06db7b01a2da9228c38783fd9f95c4fc7bba (diff) |
Add move constructor and operator to string
Diffstat (limited to 'vespalib')
-rw-r--r-- | vespalib/src/tests/stllike/string_test.cpp | 37 | ||||
-rw-r--r-- | vespalib/src/vespa/vespalib/stllike/hash_map.h | 4 | ||||
-rw-r--r-- | vespalib/src/vespa/vespalib/stllike/hash_set.h | 4 | ||||
-rw-r--r-- | vespalib/src/vespa/vespalib/stllike/hashtable.h | 8 | ||||
-rw-r--r-- | vespalib/src/vespa/vespalib/stllike/string.h | 46 | ||||
-rw-r--r-- | vespalib/src/vespa/vespalib/stllike/string.hpp | 2 | ||||
-rw-r--r-- | vespalib/src/vespa/vespalib/util/array.h | 4 | ||||
-rw-r--r-- | vespalib/src/vespa/vespalib/util/array.hpp | 4 |
8 files changed, 90 insertions, 19 deletions
diff --git a/vespalib/src/tests/stllike/string_test.cpp b/vespalib/src/tests/stllike/string_test.cpp index 885c13172b1..3ca2549b7c3 100644 --- a/vespalib/src/tests/stllike/string_test.cpp +++ b/vespalib/src/tests/stllike/string_test.cpp @@ -60,6 +60,43 @@ TEST("test self assignment of big string") { EXPECT_EQUAL(text, s); } +void verify_move_constructor(string org) { + string copy(org); + EXPECT_EQUAL(org, copy); + string moved_into(std::move(copy)); + EXPECT_EQUAL(org, moved_into); + EXPECT_NOT_EQUAL(org, copy); + EXPECT_EQUAL(string(), copy); +} + +void verify_move_operator(string org) { + string copy(org); + EXPECT_EQUAL(org, copy); + string moved_into_short("short movable string"); + EXPECT_NOT_EQUAL(org, moved_into_short); + moved_into_short = std::move(copy); + EXPECT_EQUAL(org, moved_into_short); + EXPECT_NOT_EQUAL(org, copy); + EXPECT_EQUAL(string(), copy); + + string moved_into_long("longer movable string than the 47 bytes that can be held inthe short string optimization."); + EXPECT_NOT_EQUAL(org, moved_into_long); + moved_into_long = std::move(moved_into_short); + EXPECT_EQUAL(org, moved_into_long); + EXPECT_NOT_EQUAL(org, moved_into_short); + EXPECT_EQUAL(string(), moved_into_short); +} + +void verify_move(string org) { + verify_move_constructor(org); + verify_move_operator(org); +} + +TEST("test move constructor") { + TEST_DO(verify_move("short string")); + TEST_DO(verify_move("longer string than the 47 bytes that can be held inthe short string optimization.")); +} + TEST("testStringAlloc") { fprintf(stderr, "... testing allocations\n"); string a("abcde"); diff --git a/vespalib/src/vespa/vespalib/stllike/hash_map.h b/vespalib/src/vespa/vespalib/stllike/hash_map.h index 5eae4cea55e..372178af7f5 100644 --- a/vespalib/src/vespa/vespalib/stllike/hash_map.h +++ b/vespalib/src/vespa/vespalib/stllike/hash_map.h @@ -22,8 +22,8 @@ public: typedef typename HashTable::const_iterator const_iterator; typedef typename HashTable::insert_result insert_result; public: - hash_map(hash_map &&) = default; - hash_map & operator = (hash_map &&) = default; + hash_map(hash_map &&) noexcept = default; + hash_map & operator = (hash_map &&) noexcept = default; hash_map(const hash_map &) = default; hash_map & operator = (const hash_map &) = default; hash_map(size_t reserveSize=0); diff --git a/vespalib/src/vespa/vespalib/stllike/hash_set.h b/vespalib/src/vespa/vespalib/stllike/hash_set.h index 919e5e8c47f..8d315ebfd07 100644 --- a/vespalib/src/vespa/vespalib/stllike/hash_set.h +++ b/vespalib/src/vespa/vespalib/stllike/hash_set.h @@ -19,8 +19,8 @@ public: typedef typename HashTable::const_iterator const_iterator; typedef typename HashTable::insert_result insert_result; public: - hash_set(hash_set &&) = default; - hash_set & operator = (hash_set &&) = default; + hash_set(hash_set &&) noexcept = default; + hash_set & operator = (hash_set &&) noexcept = default; hash_set(const hash_set &) = default; hash_set & operator = (const hash_set &) = default; hash_set(size_t reserveSize=0); diff --git a/vespalib/src/vespa/vespalib/stllike/hashtable.h b/vespalib/src/vespa/vespalib/stllike/hashtable.h index 4b425c4bded..ba9993c5a37 100644 --- a/vespalib/src/vespa/vespalib/stllike/hashtable.h +++ b/vespalib/src/vespa/vespalib/stllike/hashtable.h @@ -103,8 +103,8 @@ public: : _next(next), _node(node) {} hash_node(V &&node, next_t next=npos) : _next(next), _node(std::move(node)) {} - hash_node(hash_node &&) = default; - hash_node &operator=(hash_node &&) = default; + hash_node(hash_node &&) noexcept = default; + hash_node &operator=(hash_node &&) noexcept = default; hash_node(const hash_node &) = default; // These will not be created hash_node &operator=(const hash_node &) = default; // if V is non-copyable. bool operator == (const hash_node & rhs) const { @@ -221,8 +221,8 @@ public: typedef std::pair<iterator, bool> insert_result; public: - hashtable(hashtable &&) = default; - hashtable & operator = (hashtable &&) = default; + hashtable(hashtable &&) noexcept = default; + hashtable & operator = (hashtable &&) noexcept = default; hashtable(const hashtable &); hashtable & operator = (const hashtable &); hashtable(size_t reservedSpace); diff --git a/vespalib/src/vespa/vespalib/stllike/string.h b/vespalib/src/vespa/vespalib/stllike/string.h index e787ecc071f..38728da0780 100644 --- a/vespalib/src/vespa/vespalib/stllike/string.h +++ b/vespalib/src/vespa/vespalib/stllike/string.h @@ -177,6 +177,22 @@ public: small_string(const void * s, size_type sz) : _buf(_stack), _sz(sz) { init(s); } small_string(stringref s) : _buf(_stack), _sz(s.size()) { init(s.data()); } small_string(const std::string & s) : _buf(_stack), _sz(s.size()) { init(s.data()); } + small_string(small_string && rhs) noexcept + : _sz(rhs.size()), _bufferSize(rhs._bufferSize) + { + if (rhs.isAllocated()) { + _buf = rhs._buf; + rhs._buf = rhs._stack; + rhs._sz = 0; + rhs._bufferSize = sizeof(rhs._stack); + rhs._stack[0] = 0; + } else { + _buf = _stack; + memcpy(_stack, rhs._stack, sizeof(_stack)); + rhs._sz = 0; + rhs._stack[0] = 0; + } + } small_string(const small_string & rhs) noexcept : _buf(_stack), _sz(rhs.size()) { init(rhs.data()); } small_string(const small_string & rhs, size_type pos, size_type sz=npos) noexcept : _buf(_stack), _sz(std::min(sz, rhs.size()-pos)) @@ -200,7 +216,25 @@ public: free(buffer()); } } - small_string& operator= (const small_string &rhs) { + small_string& operator= (small_string && rhs) noexcept { + reset(); + _sz = rhs._sz; + _bufferSize = rhs._bufferSize; + if (rhs.isAllocated()) { + _buf = rhs._buf; + rhs._buf = rhs._stack; + rhs._sz = 0; + rhs._bufferSize = sizeof(rhs._stack); + rhs._stack[0] = 0; + } else { + _buf = _stack; + memcpy(_stack, rhs._stack, sizeof(_stack)); + rhs._sz = 0; + rhs._stack[0] = 0; + } + return *this; + } + small_string& operator= (const small_string &rhs) noexcept { return assign(rhs.data(), rhs.size()); } small_string & operator= (stringref rhs) { @@ -212,7 +246,7 @@ public: small_string& operator= (const std::string &rhs) { return operator= (stringref(rhs)); } - void swap(small_string & rhs) { + void swap(small_string & rhs) noexcept { std::swap(*this, rhs); } operator std::string () const { return std::string(c_str(), size()); } @@ -315,12 +349,12 @@ public: const char *found = (const char *)memchr(buf, c, _sz-start); return (found != NULL) ? (found - buffer()) : (size_type)npos; } - small_string & assign(const char * s) { return assign(s, strlen(s)); } - small_string & assign(const void * s, size_type sz); - small_string & assign(stringref s, size_type pos, size_type sz) { + small_string & assign(const char * s) noexcept { return assign(s, strlen(s)); } + small_string & assign(const void * s, size_type sz) noexcept; + small_string & assign(stringref s, size_type pos, size_type sz) noexcept { return assign(s.data() + pos, sz); } - small_string & assign(stringref rhs) { + small_string & assign(stringref rhs) noexcept { if (data() != rhs.data()) assign(rhs.data(), rhs.size()); return *this; } diff --git a/vespalib/src/vespa/vespalib/stllike/string.hpp b/vespalib/src/vespa/vespalib/stllike/string.hpp index bf98d82463b..f501a22adb4 100644 --- a/vespalib/src/vespa/vespalib/stllike/string.hpp +++ b/vespalib/src/vespa/vespalib/stllike/string.hpp @@ -71,7 +71,7 @@ small_string<StackSize>::rfind(const char * s, size_type e) const { template <uint32_t StackSize> small_string<StackSize> & -small_string<StackSize>::assign(const void * s, size_type sz) { +small_string<StackSize>::assign(const void * s, size_type sz) noexcept { if (__builtin_expect(capacity() >= sz, true)) { char *buf = buffer(); memmove(buf, s, sz); diff --git a/vespalib/src/vespa/vespalib/util/array.h b/vespalib/src/vespa/vespalib/util/array.h index ef39b449a45..1fdf3471fbb 100644 --- a/vespalib/src/vespa/vespalib/util/array.h +++ b/vespalib/src/vespa/vespalib/util/array.h @@ -87,12 +87,12 @@ public: Array(const Alloc & initial=Alloc::alloc()); Array(size_t sz, const Alloc & initial=Alloc::alloc()); Array(Alloc && buf, size_t sz); - Array(Array &&rhs); + Array(Array &&rhs) noexcept; Array(size_t sz, T value, const Alloc & initial=Alloc::alloc()); Array(const_iterator begin, const_iterator end, const Alloc & initial=Alloc::alloc()); Array(const Array & rhs); Array & operator =(const Array & rhs); - Array & operator =(Array && rhs); + Array & operator =(Array && rhs) noexcept; ~Array(); void swap(Array & rhs) { _array.swap(rhs._array); diff --git a/vespalib/src/vespa/vespalib/util/array.hpp b/vespalib/src/vespa/vespalib/util/array.hpp index cab9297aad9..8eb33af2a3a 100644 --- a/vespalib/src/vespa/vespalib/util/array.hpp +++ b/vespalib/src/vespa/vespalib/util/array.hpp @@ -74,7 +74,7 @@ Array<T> & Array<T>::operator =(const Array & rhs) } template <typename T> -Array<T> & Array<T>::operator =(Array && rhs) { +Array<T> & Array<T>::operator =(Array && rhs) noexcept { if (&rhs != this) { Array t(std::move(rhs)); swap(t); @@ -160,7 +160,7 @@ Array<T>::Array(Alloc && buf, size_t sz) : template <typename T> -Array<T>::Array(Array &&rhs) +Array<T>::Array(Array &&rhs) noexcept : _array(std::move(rhs._array)), _sz(rhs._sz) { |