Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/miloyip/rapidjson.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMilo Yip <miloyip@gmail.com>2021-03-30 09:31:29 +0300
committerGitHub <noreply@github.com>2021-03-30 09:31:29 +0300
commitb996a23714e0dda14913d39fda809af170fbb6e9 (patch)
tree18d04aecf742b2af6987ff042aa2f13925ed6921
parentcd5ee4dfe9814fa88b7ba66c1f9d8176d154c62f (diff)
parent08cf9a56c0f3d648ef615c3d5f60d08941ebd3ec (diff)
Merge pull request #1866 from ylavic/std_allocator_traits
Make StdAllocator C++17-20 compatible.
-rw-r--r--include/rapidjson/allocators.h73
-rw-r--r--include/rapidjson/rapidjson.h31
-rw-r--r--test/unittest/allocatorstest.cpp6
3 files changed, 84 insertions, 26 deletions
diff --git a/include/rapidjson/allocators.h b/include/rapidjson/allocators.h
index 03b2dcc0..2871542f 100644
--- a/include/rapidjson/allocators.h
+++ b/include/rapidjson/allocators.h
@@ -19,6 +19,10 @@
#include <memory>
+#if RAPIDJSON_HAS_CXX11
+#include <type_traits>
+#endif
+
RAPIDJSON_NAMESPACE_BEGIN
///////////////////////////////////////////////////////////////////////////////
@@ -420,6 +424,11 @@ class StdAllocator :
public std::allocator<T>
{
typedef std::allocator<T> allocator_type;
+#if RAPIDJSON_HAS_CXX11
+ typedef std::allocator_traits<allocator_type> traits_type;
+#else
+ typedef allocator_type traits_type;
+#endif
public:
typedef BaseAllocator BaseAllocatorType;
@@ -449,30 +458,52 @@ public:
~StdAllocator() RAPIDJSON_NOEXCEPT
{ }
- typedef typename allocator_type::value_type value_type;
- typedef typename allocator_type::pointer pointer;
- typedef typename allocator_type::const_pointer const_pointer;
- typedef typename allocator_type::reference reference;
- typedef typename allocator_type::const_reference const_reference;
- typedef typename allocator_type::size_type size_type;
- typedef typename allocator_type::difference_type difference_type;
-
template<typename U>
struct rebind {
typedef StdAllocator<U, BaseAllocator> other;
};
+ typedef typename traits_type::size_type size_type;
+ typedef typename traits_type::difference_type difference_type;
+
+ typedef typename traits_type::value_type value_type;
+ typedef typename traits_type::pointer pointer;
+ typedef typename traits_type::const_pointer const_pointer;
+
#if RAPIDJSON_HAS_CXX11
- using allocator_type::max_size;
- using allocator_type::address;
- using allocator_type::construct;
- using allocator_type::destroy;
-#else
- size_t max_size() const RAPIDJSON_NOEXCEPT
+
+ typedef typename std::add_lvalue_reference<value_type>::type &reference;
+ typedef typename std::add_lvalue_reference<typename std::add_const<value_type>::type>::type &const_reference;
+
+ pointer address(reference r) const RAPIDJSON_NOEXCEPT
{
- return allocator_type::max_size();
+ return std::addressof(r);
+ }
+ const_pointer address(const_reference r) const RAPIDJSON_NOEXCEPT
+ {
+ return std::addressof(r);
+ }
+
+ size_type max_size() const RAPIDJSON_NOEXCEPT
+ {
+ return traits_type::max_size(*this);
+ }
+
+ template <typename ...Args>
+ void construct(pointer p, Args&&... args)
+ {
+ traits_type::construct(*this, p, std::forward<Args>(args)...);
+ }
+ void destroy(pointer p)
+ {
+ traits_type::destroy(*this, p);
}
+#else // !RAPIDJSON_HAS_CXX11
+
+ typedef typename allocator_type::reference reference;
+ typedef typename allocator_type::const_reference const_reference;
+
pointer address(reference r) const RAPIDJSON_NOEXCEPT
{
return allocator_type::address(r);
@@ -482,6 +513,11 @@ public:
return allocator_type::address(r);
}
+ size_type max_size() const RAPIDJSON_NOEXCEPT
+ {
+ return allocator_type::max_size();
+ }
+
void construct(pointer p, const_reference r)
{
allocator_type::construct(p, r);
@@ -490,7 +526,8 @@ public:
{
allocator_type::destroy(p);
}
-#endif
+
+#endif // !RAPIDJSON_HAS_CXX11
template <typename U>
U* allocate(size_type n = 1, const void* = 0)
@@ -578,13 +615,13 @@ public:
~StdAllocator() RAPIDJSON_NOEXCEPT
{ }
- typedef typename allocator_type::value_type value_type;
-
template<typename U>
struct rebind {
typedef StdAllocator<U, BaseAllocator> other;
};
+ typedef typename allocator_type::value_type value_type;
+
private:
template <typename, typename>
friend class StdAllocator; // access to StdAllocator<!T>.*
diff --git a/include/rapidjson/rapidjson.h b/include/rapidjson/rapidjson.h
index 8034c493..10935818 100644
--- a/include/rapidjson/rapidjson.h
+++ b/include/rapidjson/rapidjson.h
@@ -125,6 +125,19 @@
#endif
///////////////////////////////////////////////////////////////////////////////
+// __cplusplus macro
+
+//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
+
+#if defined(_MSC_VER)
+#define RAPIDJSON_CPLUSPLUS _MSVC_LANG
+#else
+#define RAPIDJSON_CPLUSPLUS __cplusplus
+#endif
+
+//!@endcond
+
+///////////////////////////////////////////////////////////////////////////////
// RAPIDJSON_HAS_STDSTRING
#ifndef RAPIDJSON_HAS_STDSTRING
@@ -411,7 +424,7 @@ RAPIDJSON_NAMESPACE_END
// Prefer C++11 static_assert, if available
#ifndef RAPIDJSON_STATIC_ASSERT
-#if __cplusplus >= 201103L || ( defined(_MSC_VER) && _MSC_VER >= 1800 )
+#if RAPIDJSON_CPLUSPLUS >= 201103L || ( defined(_MSC_VER) && _MSC_VER >= 1800 )
#define RAPIDJSON_STATIC_ASSERT(x) \
static_assert(x, RAPIDJSON_STRINGIFY(x))
#endif // C++11
@@ -542,7 +555,7 @@ RAPIDJSON_NAMESPACE_END
// C++11 features
#ifndef RAPIDJSON_HAS_CXX11
-#define RAPIDJSON_HAS_CXX11 (__cplusplus >= 201103L)
+#define RAPIDJSON_HAS_CXX11 (RAPIDJSON_CPLUSPLUS >= 201103L)
#endif
#ifndef RAPIDJSON_HAS_CXX11_RVALUE_REFS
@@ -610,9 +623,17 @@ RAPIDJSON_NAMESPACE_END
///////////////////////////////////////////////////////////////////////////////
// C++17 features
-#if defined(__has_cpp_attribute)
-# if __has_cpp_attribute(fallthrough)
-# define RAPIDJSON_DELIBERATE_FALLTHROUGH [[fallthrough]]
+#ifndef RAPIDJSON_HAS_CXX17
+#define RAPIDJSON_HAS_CXX17 (RAPIDJSON_CPLUSPLUS >= 201703L)
+#endif
+
+#if RAPIDJSON_HAS_CXX17
+# define RAPIDJSON_DELIBERATE_FALLTHROUGH [[fallthrough]]
+#elif defined(__has_cpp_attribute)
+# if __has_cpp_attribute(clang::fallthrough)
+# define RAPIDJSON_DELIBERATE_FALLTHROUGH [[clang::fallthrough]]
+# elif __has_cpp_attribute(fallthrough)
+# define RAPIDJSON_DELIBERATE_FALLTHROUGH __attribute__((fallthrough))
# else
# define RAPIDJSON_DELIBERATE_FALLTHROUGH
# endif
diff --git a/test/unittest/allocatorstest.cpp b/test/unittest/allocatorstest.cpp
index b8a21913..76e34b53 100644
--- a/test/unittest/allocatorstest.cpp
+++ b/test/unittest/allocatorstest.cpp
@@ -107,12 +107,12 @@ void TestStdAllocator(const Allocator& a) {
arr[i] = 0x0f0f0f0f;
}
ia.deallocate(arr, 10);
- arr = (int *)ia.Malloc(10 * sizeof(int));
+ arr = Malloc<int>(ia, 10);
EXPECT_TRUE(arr != 0);
for (int i = 0; i < 10; ++i) {
arr[i] = 0x0f0f0f0f;
}
- arr = (int *)ia.Realloc(arr, 10 * sizeof(int), 20 * sizeof(int));
+ arr = Realloc<int>(ia, arr, 10, 20);
EXPECT_TRUE(arr != 0);
for (int i = 0; i < 10; ++i) {
EXPECT_EQ(arr[i], 0x0f0f0f0f);
@@ -120,7 +120,7 @@ void TestStdAllocator(const Allocator& a) {
for (int i = 10; i < 20; i++) {
arr[i] = 0x0f0f0f0f;
}
- ia.Free(arr);
+ Free<int>(ia, arr, 20);
int cons = 0, dest = 0;
StdAllocator<TestStdAllocatorData, Allocator> da(a);