DAW JSON Link
daw_json_allocator_wrapper.h
Go to the documentation of this file.
1 // Copyright (c) Darrell Wright
2 //
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
5 //
6 // Official repository: https://github.com/beached/daw_json_link
7 //
8 
9 #pragma once
10 
11 #include "version.h"
12 
13 #include "daw_json_assert.h"
14 
15 #include <memory>
16 #include <optional>
17 #include <type_traits>
18 
19 namespace daw::json {
20  inline namespace DAW_JSON_VER {
21  namespace json_details {
22  template<typename Alloc, bool /*is_empty*/>
23  class AllocatorWrapperBase {
24  using allocator_t = std::remove_reference_t<Alloc>;
25  std::optional<allocator_t const *> allocator_ptr;
26 
27  public:
28  explicit AllocatorWrapperBase( ) = default;
29  explicit constexpr AllocatorWrapperBase(
30  allocator_t const &alloc ) noexcept
31  : allocator_ptr( &alloc ) {}
32 
33  [[nodiscard]] constexpr allocator_t const &get_allocator( ) const {
34  daw_json_ensure( allocator_ptr.has_value( ),
35  ErrorReason::UnexpectedNull );
36  return **allocator_ptr;
37  }
38  };
39 
40  template<typename Alloc>
41  class AllocatorWrapperBase<Alloc, true /*is_empty*/> {
42  using has_stateless_allocator = void;
43  using allocator_t = std::remove_reference_t<Alloc>;
44  static constexpr allocator_t allocator{ };
45 
46  public:
47  explicit AllocatorWrapperBase( ) = default;
48  explicit constexpr AllocatorWrapperBase(
49  allocator_t const & ) noexcept {}
50 
51  [[nodiscard]] constexpr allocator_t const &get_allocator( ) const {
52  return allocator;
53  }
54  };
55 
57  allocator_has_rebind_v,
58  typename std::allocator_traits<T>::template rebind_traits<U>::type );
59 
60  template<typename Alloc>
61  struct AllocatorWrapper
62  : AllocatorWrapperBase<Alloc, std::is_empty_v<Alloc>> {
63  using allocator_type = std::remove_reference_t<Alloc>;
64 
65  using AllocatorWrapperBase<Alloc,
66  std::is_empty_v<Alloc>>::get_allocator;
67 
68  explicit AllocatorWrapper( ) = default;
69  explicit constexpr AllocatorWrapper(
70  allocator_type const &alloc ) noexcept
71  : AllocatorWrapperBase<allocator_type,
72  std::is_empty_v<allocator_type>>( alloc ) {}
73 
74  static constexpr bool has_allocator = true;
75 
76  template<typename A, typename T>
77  struct allocator_type_as_rebind {
78  using type =
79  typename std::allocator_traits<A>::template rebind_alloc<T>;
80  };
81 
82  template<typename A, typename T>
83  static constexpr bool has_rebind_v = allocator_has_rebind_v<A, T>;
84 
85  // DAW FIX
86  template<typename T>
87  using allocator_type_as = typename std::allocator_traits<
88  allocator_type>::template rebind_alloc<T>;
89 
90  template<typename T>
91  [[nodiscard]] constexpr auto get_allocator_for( ) const {
92  return static_cast<allocator_type_as<T>>( this->get_allocator( ) );
93  }
94  };
95 
96  struct NoAllocator {};
97 
98  template<>
99  class AllocatorWrapper<NoAllocator> {
100  public:
101  explicit AllocatorWrapper( ) = default;
102  explicit constexpr AllocatorWrapper( NoAllocator const & ) noexcept {}
103 
104  static constexpr bool has_allocator = false;
105 
106  using allocator_type = std::allocator<char>;
107 
108  template<typename T>
109  using allocator_type_as = std::allocator<T>;
110 
111  template<typename T>
112  [[nodiscard]] constexpr static std::allocator<T> get_allocator_for( ) {
113  return std::allocator<T>( );
114  }
115 
116  [[nodiscard]] DAW_CONSTEVAL static NoAllocator get_allocator( ) {
117  return { };
118  }
119  };
120  } // namespace json_details
121  } // namespace DAW_JSON_VER
122 } // namespace daw::json
#define daw_json_ensure(Bool,...)
Ensure that Bool is true. If false pass rest of args to daw_json_error.
#define DAW_JSON_MAKE_REQ_TYPE_ALIAS_TRAIT2(Name,...)
Customization point traits.
#define DAW_JSON_VER
The version string used in namespace definitions. Must be a valid namespace name.
Definition: version.h:25