Skip to content

Commit 03676c9

Browse files
authored
Merge pull request Tencent#1870 from ylavic/allocators_rvalues
Add rvalue copy and assignment to MemoryPoolAllocator and StdAllocator.
2 parents 49aa0fc + aa0675f commit 03676c9

File tree

3 files changed

+72
-8
lines changed

3 files changed

+72
-8
lines changed

.travis.yml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,10 @@ matrix:
4040
- env: CONF=debug ARCH=x86_64 CXX11=OFF CXX17=OFF
4141
compiler: gcc
4242
arch: amd64
43-
- env: CONF=debug ARCH=x86 CXX11=OFF CXX17=ON
43+
- env: CONF=debug ARCH=x86 CXX11=OFF CXX17=ON CXX_FLAGS='-D_GLIBCXX_DEBUG'
4444
compiler: gcc
45-
arch: amd64
46-
- env: CONF=debug ARCH=x86_64 CXX11=OFF CXX17=ON
45+
arch: amd64/
46+
- env: CONF=debug ARCH=x86_64 CXX11=OFF CXX17=ON CXX_FLAGS='-D_GLIBCXX_DEBUG'
4747
compiler: gcc
4848
arch: amd64
4949
- env: CONF=release ARCH=aarch64 CXX11=ON CXX17=OFF
@@ -84,7 +84,7 @@ matrix:
8484
compiler: clang
8585
arch: arm64
8686
# coverage report
87-
- env: CONF=debug ARCH=x86 CXX11=ON CXX17=OFF GCOV_FLAGS='--coverage'
87+
- env: CONF=debug ARCH=x86 GCOV_FLAGS='--coverage' CXX_FLAGS='-O0' CXX11=OFF CXX17=OFF
8888
compiler: gcc
8989
arch: amd64
9090
cache:
@@ -93,7 +93,7 @@ matrix:
9393
after_success:
9494
- pip install --user cpp-coveralls
9595
- coveralls -r .. --gcov-options '\-lp' -e thirdparty -e example -e test -e build/CMakeFiles -e include/rapidjson/msinttypes -e include/rapidjson/internal/meta.h -e include/rapidjson/error/en.h
96-
- env: CONF=debug ARCH=x86_64 GCOV_FLAGS='--coverage'
96+
- env: CONF=debug ARCH=x86_64 GCOV_FLAGS='--coverage' CXX_FLAGS='-O0' CXX11=ON CXX17=OFF
9797
compiler: gcc
9898
arch: amd64
9999
cache:
@@ -102,7 +102,7 @@ matrix:
102102
after_success:
103103
- pip install --user cpp-coveralls
104104
- coveralls -r .. --gcov-options '\-lp' -e thirdparty -e example -e test -e build/CMakeFiles -e include/rapidjson/msinttypes -e include/rapidjson/internal/meta.h -e include/rapidjson/error/en.h
105-
- env: CONF=debug ARCH=aarch64 GCOV_FLAGS='--coverage'
105+
- env: CONF=debug ARCH=aarch64 GCOV_FLAGS='--coverage' CXX_FLAGS='-O0' CXX11=OFF CXX17=ON
106106
compiler: gcc
107107
arch: arm64
108108
cache:
@@ -150,7 +150,7 @@ script:
150150
-DRAPIDJSON_BUILD_CXX17=$CXX17
151151
-DCMAKE_VERBOSE_MAKEFILE=ON
152152
-DCMAKE_BUILD_TYPE=$CONF
153-
-DCMAKE_CXX_FLAGS="$ARCH_FLAGS $GCOV_FLAGS"
153+
-DCMAKE_CXX_FLAGS="$ARCH_FLAGS $GCOV_FLAGS $CXX_FLAGS"
154154
-DCMAKE_EXE_LINKER_FLAGS=$GCOV_FLAGS
155155
..)
156156
- cd build

include/rapidjson/allocators.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,18 +222,42 @@ class MemoryPoolAllocator {
222222
{
223223
RAPIDJSON_NOEXCEPT_ASSERT(rhs.shared_->refcount > 0);
224224
++rhs.shared_->refcount;
225+
this->~MemoryPoolAllocator();
226+
baseAllocator_ = rhs.baseAllocator_;
227+
chunk_capacity_ = rhs.chunk_capacity_;
228+
shared_ = rhs.shared_;
229+
return *this;
230+
}
225231

232+
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
233+
MemoryPoolAllocator(MemoryPoolAllocator&& rhs) RAPIDJSON_NOEXCEPT :
234+
chunk_capacity_(rhs.chunk_capacity_),
235+
baseAllocator_(rhs.baseAllocator_),
236+
shared_(rhs.shared_)
237+
{
238+
RAPIDJSON_NOEXCEPT_ASSERT(rhs.shared_->refcount > 0);
239+
rhs.shared_ = 0;
240+
}
241+
MemoryPoolAllocator& operator=(MemoryPoolAllocator&& rhs) RAPIDJSON_NOEXCEPT
242+
{
243+
RAPIDJSON_NOEXCEPT_ASSERT(rhs.shared_->refcount > 0);
226244
this->~MemoryPoolAllocator();
227245
baseAllocator_ = rhs.baseAllocator_;
228246
chunk_capacity_ = rhs.chunk_capacity_;
229247
shared_ = rhs.shared_;
248+
rhs.shared_ = 0;
230249
return *this;
231250
}
251+
#endif
232252

233253
//! Destructor.
234254
/*! This deallocates all memory chunks, excluding the user-supplied buffer.
235255
*/
236256
~MemoryPoolAllocator() RAPIDJSON_NOEXCEPT {
257+
if (!shared_) {
258+
// do nothing if moved
259+
return;
260+
}
237261
if (shared_->refcount > 1) {
238262
--shared_->refcount;
239263
return;
@@ -449,6 +473,17 @@ class StdAllocator :
449473
baseAllocator_(rhs.baseAllocator_)
450474
{ }
451475

476+
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
477+
StdAllocator(StdAllocator&& rhs) RAPIDJSON_NOEXCEPT :
478+
allocator_type(std::move(rhs)),
479+
baseAllocator_(std::move(rhs.baseAllocator_))
480+
{ }
481+
#endif
482+
#if RAPIDJSON_HAS_CXX11
483+
using propagate_on_container_move_assignment = std::true_type;
484+
using propagate_on_container_swap = std::true_type;
485+
#endif
486+
452487
/* implicit */
453488
StdAllocator(const BaseAllocator& allocator) RAPIDJSON_NOEXCEPT :
454489
allocator_type(),
@@ -549,6 +584,10 @@ class StdAllocator :
549584
deallocate<value_type>(p, n);
550585
}
551586

587+
#if RAPIDJSON_HAS_CXX11
588+
using is_always_equal = std::is_empty<BaseAllocator>;
589+
#endif
590+
552591
template<typename U>
553592
bool operator==(const StdAllocator<U, BaseAllocator>& rhs) const RAPIDJSON_NOEXCEPT
554593
{
@@ -561,6 +600,7 @@ class StdAllocator :
561600
}
562601

563602
//! rapidjson Allocator concept
603+
static const bool kNeedFree = BaseAllocator::kNeedFree;
564604
void* Malloc(size_t size)
565605
{
566606
return baseAllocator_.Malloc(size);

test/unittest/allocatorstest.cpp

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@
1616

1717
#include "rapidjson/allocators.h"
1818

19+
#include <map>
1920
#include <string>
20-
#include <cstring>
21+
#include <utility>
22+
#include <functional>
2123

2224
using namespace rapidjson;
2325

@@ -141,12 +143,34 @@ void TestStdAllocator(const Allocator& a) {
141143

142144
typedef StdAllocator<char, Allocator> CharAllocator;
143145
typedef std::basic_string<char, std::char_traits<char>, CharAllocator> String;
146+
#if RAPIDJSON_HAS_CXX11
147+
String s(CharAllocator{a});
148+
#else
144149
CharAllocator ca(a);
145150
String s(ca);
151+
#endif
146152
for (int i = 0; i < 26; i++) {
147153
s.push_back(static_cast<char>('A' + i));
148154
}
149155
EXPECT_TRUE(s == "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
156+
157+
typedef StdAllocator<std::pair<const int, bool>, Allocator> MapAllocator;
158+
typedef std::map<int, bool, std::less<int>, MapAllocator> Map;
159+
#if RAPIDJSON_HAS_CXX11
160+
Map map(std::less<int>(), MapAllocator{a});
161+
#else
162+
MapAllocator ma(a);
163+
Map map(std::less<int>(), ma);
164+
#endif
165+
for (int i = 0; i < 10; i++) {
166+
map.insert(std::make_pair(i, (i % 2) == 0));
167+
}
168+
EXPECT_TRUE(map.size() == 10);
169+
for (int i = 0; i < 10; i++) {
170+
typename Map::iterator it = map.find(i);
171+
EXPECT_TRUE(it != map.end());
172+
EXPECT_TRUE(it->second == ((i % 2) == 0));
173+
}
150174
}
151175

152176
TEST(Allocator, CrtAllocator) {

0 commit comments

Comments
 (0)