Skip to content

Commit

Permalink
Make StdAllocator C++17-20 compatible.
Browse files Browse the repository at this point in the history
  • Loading branch information
ylavic committed Mar 28, 2021
1 parent cd5ee4d commit 923ae7c
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 24 deletions.
67 changes: 52 additions & 15 deletions include/rapidjson/allocators.h
Expand Up @@ -19,6 +19,11 @@

#include <memory>

#if RAPIDJSON_HAS_CXX11
#include <limits>
#include <type_traits>
#endif

RAPIDJSON_NAMESPACE_BEGIN

///////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -420,6 +425,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;
Expand Down Expand Up @@ -449,29 +459,50 @@ class StdAllocator :
~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

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 std::addressof(r);
}
const_pointer address(const_reference r) const RAPIDJSON_NOEXCEPT
{
return std::addressof(r);
}

size_t max_size() const RAPIDJSON_NOEXCEPT
{
return allocator_type::max_size();
return std::numeric_limits<size_type>::max() / sizeof(value_type);
}

template <typename ...Args>
void construct(pointer p, Args &&...args)
{
::new (static_cast<void*>(p)) value_type(std::forward<Args>(args)...);
}
void destroy(pointer p)
{
p->~T();
}

#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
{
Expand All @@ -482,6 +513,11 @@ class StdAllocator :
return allocator_type::address(r);
}

size_t max_size() const RAPIDJSON_NOEXCEPT
{
return allocator_type::max_size();
}

void construct(pointer p, const_reference r)
{
allocator_type::construct(p, r);
Expand All @@ -490,7 +526,8 @@ class StdAllocator :
{
allocator_type::destroy(p);
}
#endif

#endif // !RAPIDJSON_HAS_CXX11

template <typename U>
U* allocate(size_type n = 1, const void* = 0)
Expand Down
14 changes: 8 additions & 6 deletions include/rapidjson/rapidjson.h
Expand Up @@ -610,12 +610,14 @@ RAPIDJSON_NAMESPACE_END
///////////////////////////////////////////////////////////////////////////////
// C++17 features

#if defined(__has_cpp_attribute)
# if __has_cpp_attribute(fallthrough)
# define RAPIDJSON_DELIBERATE_FALLTHROUGH [[fallthrough]]
# else
# define RAPIDJSON_DELIBERATE_FALLTHROUGH
# endif
#ifndef RAPIDJSON_HAS_CXX17
#define RAPIDJSON_HAS_CXX17 (__cplusplus >= 201703L)
#endif

#if RAPIDJSON_HAS_CXX17
# define RAPIDJSON_DELIBERATE_FALLTHROUGH [[fallthrough]]
#elif defined(__has_cpp_attribute) && __has_cpp_attribute(fallthrough)
# define RAPIDJSON_DELIBERATE_FALLTHROUGH __attribute__((fallthrough))
#else
# define RAPIDJSON_DELIBERATE_FALLTHROUGH
#endif
Expand Down
6 changes: 3 additions & 3 deletions test/unittest/allocatorstest.cpp
Expand Up @@ -107,20 +107,20 @@ 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);
}
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);
Expand Down

0 comments on commit 923ae7c

Please sign in to comment.