24#ifndef MEMORY_UNIQUE_PTR_INCLUDED
25#define MEMORY_UNIQUE_PTR_INCLUDED
51 ->
decltype(std::declval<T>().allocate(std::declval<size_t>()),
62struct is_allocator : decltype(traits::test_for_allocate<T>(nullptr)) {};
122 template <
class U,
class... Args>
151template <
typename T,
typename A = std::
nullptr_t>
162 typename D = T,
typename B = A,
163 std::enable_if_t<std::is_same<B, std::nullptr_t>::value> * =
nullptr>
172 typename D = T,
typename B = A,
173 std::enable_if_t<!std::is_same<B, std::nullptr_t>::value> * =
nullptr>
183 template <
typename D = T,
typename B = A,
184 std::enable_if_t<!std::is_same<B, std::nullptr_t>::value &&
185 std::is_array<D>::value> * =
nullptr>
194 template <
typename D = T,
typename B = A,
195 std::enable_if_t<std::is_same<B, std::nullptr_t>::value &&
196 std::is_array<D>::value> * =
nullptr>
206 template <
typename... Args,
typename D = T,
typename B = A,
207 std::enable_if_t<!std::is_same<B, std::nullptr_t>::value &&
208 !std::is_array<D>::value> * =
nullptr>
217 template <
typename... Args,
typename D = T,
typename B = A,
218 std::enable_if_t<std::is_same<B, std::nullptr_t>::value &&
219 !std::is_array<D>::value> * =
nullptr>
246 template <
typename D = T,
247 std::enable_if_t<!std::is_array<D>::value> * =
nullptr>
262 template <
typename D = T,
263 std::enable_if_t<std::is_array<D>::value> * =
nullptr>
270 operator bool()
const;
280 std::enable_if_t<std::is_same<B, std::nullptr_t>::value> * =
nullptr>
291 std::enable_if_t<!std::is_same<B, std::nullptr_t>::value> * =
nullptr>
315 typename D = T,
typename B = A,
316 std::enable_if_t<std::is_array<D>::value &&
317 std::is_same<B, std::nullptr_t>::value> * =
nullptr>
329 typename D = T,
typename B = A,
330 std::enable_if_t<std::is_array<D>::value &&
331 !std::is_same<B, std::nullptr_t>::value> * =
nullptr>
355 template <
typename D = T,
typename B = A,
356 std::enable_if_t<std::is_same<B, std::nullptr_t>::value &&
357 std::is_array<D>::value> * =
nullptr>
362 template <
typename D = T,
typename B = A,
363 std::enable_if_t<std::is_same<B, std::nullptr_t>::value &&
364 !std::is_array<D>::value> * =
nullptr>
369 template <
typename D = T,
typename B = A,
370 std::enable_if_t<!std::is_same<B, std::nullptr_t>::value &&
371 std::is_array<D>::value> * =
nullptr>
376 template <
typename D = T,
typename B = A,
377 std::enable_if_t<!std::is_same<B, std::nullptr_t>::value &&
378 !std::is_array<D>::value> * =
nullptr>
385 template <
typename D = T,
386 std::enable_if_t<std::is_array<D>::value> * =
nullptr>
393 template <
typename D = T,
394 std::enable_if_t<!std::is_array<D>::value> * =
nullptr>
406template <typename T, std::enable_if_t<std::is_array<T>::value> * =
nullptr>
417template <
typename T,
typename A,
418 std::enable_if_t<std::is_array<T>::value> * =
nullptr>
429template <
typename T,
typename A,
typename... Args,
430 std::enable_if_t<!std::is_array<T>::value &&
441template <
typename T,
typename... Args,
442 std::enable_if_t<!std::is_array<T>::value> * =
nullptr>
447template <
typename T,
typename U>
450 return lhs.
key() == rhs.
key();
453template <
typename T,
typename U>
456 return lhs.
key() != rhs.
key();
459template <
typename T1,
typename A1,
typename T2,
typename A2>
462 return static_cast<const void *
>(lhs.
get()) ==
463 static_cast<const void *
>(rhs.
get());
466template <
typename T1,
typename A1,
typename T2,
typename A2>
469 return !(lhs == rhs);
472template <
typename T1,
typename A1>
474 return lhs.
get() ==
nullptr;
477template <
typename T1,
typename A1>
479 return !(lhs ==
nullptr);
489 : m_key{rhs.m_key} {}
505 if (
n <= std::numeric_limits<std::size_t>::max() /
sizeof(T)) {
506 if (
auto p =
static_cast<T *
>(
my_malloc(this->m_key, (
n *
sizeof(T)),
510 throw std::bad_alloc();
519template <
class U,
class... Args>
521 assert(
p !=
nullptr);
523 ::new ((
void *)
p)
U(std::forward<Args>(args)...);
531 assert(
p !=
nullptr);
541 return std::numeric_limits<size_t>::max() /
sizeof(T);
544template <
typename T,
typename A>
545template <
typename D,
typename B,
546 std::enable_if_t<std::is_same<B, std::nullptr_t>::value> *>
549template <
typename T,
typename A>
550template <
typename D,
typename B,
551 std::enable_if_t<!std::is_same<B, std::nullptr_t>::value> *>
553 : m_underlying{
nullptr}, m_allocator{alloc}, m_size{0} {}
555template <
typename T,
typename A>
556template <
typename D,
typename B,
557 std::enable_if_t<!std::is_same<B, std::nullptr_t>::value &&
558 std::is_array<D>::value> *>
560 : m_underlying{
nullptr}, m_allocator{alloc}, m_size{size} {
564template <
typename T,
typename A>
565template <
typename D,
typename B,
566 std::enable_if_t<std::is_same<B, std::nullptr_t>::value &&
567 std::is_array<D>::value> *>
569 : m_underlying{new
type[size]}, m_size{size} {}
571template <
typename T,
typename A>
572template <
typename... Args,
typename D,
typename B,
573 std::enable_if_t<!std::is_same<B, std::nullptr_t>::value &&
574 !std::is_array<D>::value> *>
576 : m_underlying{
nullptr}, m_allocator{alloc}, m_size{sizeof(T)} {
581template <
typename T,
typename A>
582template <
typename... Args,
typename D,
typename B,
583 std::enable_if_t<std::is_same<B, std::nullptr_t>::value &&
584 !std::is_array<D>::value> *>
586 : m_underlying{new T{
std::forward<Args>(args)...}}, m_size{sizeof(T)} {}
588template <
typename T,
typename A>
590 : m_underlying{rhs.m_underlying},
591 m_allocator{rhs.m_allocator},
596template <
typename T,
typename A>
601template <
typename T,
typename A>
604 this->m_underlying = rhs.m_underlying;
605 this->m_allocator = rhs.m_allocator;
606 this->m_size = rhs.m_size;
611template <
typename T,
typename A>
612template <typename D, std::enable_if_t<!std::is_array<D>::value> *>
615 return this->m_underlying;
618template <
typename T,
typename A>
621 return (*this->m_underlying);
624template <
typename T,
typename A>
625template <typename D, std::enable_if_t<std::is_array<D>::value> *>
628 return this->m_underlying[index];
631template <
typename T,
typename A>
633 return this->m_underlying !=
nullptr;
636template <
typename T,
typename A>
638 std::enable_if_t<std::is_same<B, std::nullptr_t>::value> *>
640 pointer to_return = this->m_underlying;
645template <
typename T,
typename A>
647 std::enable_if_t<!std::is_same<B, std::nullptr_t>::value> *>
649 pointer to_return = this->m_allocator->release(this->m_underlying);
650 if (to_return != this->m_underlying) {
651 to_return = this->
clone();
659template <
typename T,
typename A>
662 return this->m_underlying;
665template <
typename T,
typename A>
670template <
typename T,
typename A>
671template <
typename D,
typename B,
672 std::enable_if_t<std::is_array<D>::value &&
673 std::is_same<B, std::nullptr_t>::value> *>
676 pointer old_ptr = this->m_underlying;
677 this->m_underlying =
new type[new_size];
678 if (this->m_size != 0) {
679 std::copy(old_ptr, old_ptr + std::min(this->m_size, new_size),
682 this->m_size = new_size;
687template <
typename T,
typename A>
688template <
typename D,
typename B,
689 std::enable_if_t<std::is_array<D>::value &&
690 !std::is_same<B, std::nullptr_t>::value> *>
693 if (this->m_allocator->can_resize()) {
695 this->m_allocator->resize(this->m_underlying, this->m_size, new_size);
697 pointer old_ptr = this->m_underlying;
698 this->m_underlying = this->m_allocator->allocate(new_size);
699 if (this->m_size != 0) {
700 std::copy(old_ptr, old_ptr + std::min(this->m_size, new_size),
702 this->m_allocator->deallocate(old_ptr, this->m_size);
705 this->m_size = new_size;
709template <
typename T,
typename A>
711 return *this->m_allocator;
714template <
typename T,
typename A>
716 this->m_underlying =
nullptr;
720template <
typename T,
typename A>
721template <
typename D,
typename B,
722 std::enable_if_t<std::is_same<B, std::nullptr_t>::value &&
723 std::is_array<D>::value> *>
725 if (this->m_underlying !=
nullptr) {
726 delete[] this->m_underlying;
731template <
typename T,
typename A>
732template <
typename D,
typename B,
733 std::enable_if_t<std::is_same<B, std::nullptr_t>::value &&
734 !std::is_array<D>::value> *>
736 if (this->m_underlying !=
nullptr) {
737 delete this->m_underlying;
742template <
typename T,
typename A>
743template <
typename D,
typename B,
744 std::enable_if_t<!std::is_same<B, std::nullptr_t>::value &&
745 std::is_array<D>::value> *>
747 if (this->m_underlying !=
nullptr) {
748 this->m_allocator->deallocate(this->m_underlying, this->m_size);
753template <
typename T,
typename A>
754template <
typename D,
typename B,
755 std::enable_if_t<!std::is_same<B, std::nullptr_t>::value &&
756 !std::is_array<D>::value> *>
758 if (this->m_underlying !=
nullptr) {
759 this->m_allocator->destroy(this->m_underlying);
760 this->m_allocator->deallocate(this->m_underlying, this->m_size);
765template <
typename T,
typename A>
766template <typename D, std::enable_if_t<std::is_array<D>::value> *>
770 std::copy(this->m_underlying, this->m_underlying + this->m_size, to_return);
774template <
typename T,
typename A>
775template <typename D, std::enable_if_t<!std::is_array<D>::value> *>
778 pointer to_return =
new type(*this->m_underlying);
783template <typename T, std::enable_if_t<std::is_array<T>::value> *>
788template <typename T, typename A, std::enable_if_t<std::is_array<T>::value> *>
793template <
typename T,
typename A,
typename... Args,
794 std::enable_if_t<!std::is_array<T>::value &&
801template <
typename T,
typename... Args,
802 std::enable_if_t<!std::is_array<T>::value> *>
Allocator class for instrumenting allocated memory with Performance Schema keys.
Definition: unique_ptr.h:69
size_type max_size() const
The maximum size available to allocate.
Definition: unique_ptr.h:540
size_t size_type
Definition: unique_ptr.h:71
T value_type
Definition: unique_ptr.h:70
void construct(U *p, Args &&...args)
In-place constructs an object of class U in the memory pointed by p.
Definition: unique_ptr.h:520
PSI_memory_key key() const
Retrieves the PFS for this allocator object.
Definition: unique_ptr.h:499
PSI_memory_key m_key
The PFS key to be used to allocate memory.
Definition: unique_ptr.h:139
void destroy(T *p)
In-place invokes the destructor for class T on object pointed by p.
Definition: unique_ptr.h:530
PFS_allocator(PSI_memory_key key)
Constructor for the class that takes the PFS key to be used.
Definition: unique_ptr.h:484
T * allocate(std::size_t n)
Allocate n bytes and return a pointer to the beginning of the allocated memory.
Definition: unique_ptr.h:504
void deallocate(T *p, std::size_t n) noexcept
Deallocates the n bytes stored in the memory pointer p is pointing to.
Definition: unique_ptr.h:514
Class that holds the pointer to a variable in a static and non-destructible way.
Definition: ref_ptr.h:46
Smart pointer to hold a unique pointer to a heap allocated memory of type T, constructed using a spec...
Definition: unique_ptr.h:152
size_t size() const
The size of the memory allocated, in bytes.
Definition: unique_ptr.h:666
Unique_ptr< T, A > & operator=(Unique_ptr< T, A > const &rhs)=delete
pointer clone() const
Clones the underlying memory and returns a pointer to the clone memory.
virtual ~Unique_ptr()
Destructor for the class.
Definition: unique_ptr.h:597
Unique_ptr< T, A > & reserve(size_t new_size)
Will resize the allocated memory to new_size.
reference operator[](size_t index) const
Subscript operator, to access an array element when T is of array type.
pointer get() const
Returns a pointer to the underlying allocated memory.
Definition: unique_ptr.h:660
memory::Ref_ptr< A > m_allocator
The allocator to be used to allocate memory.
Definition: unique_ptr.h:344
pointer operator->() const
Arrow operator to access the underlying object of type T.
A & allocator() const
Returns the used allocator instance, if any.
Definition: unique_ptr.h:710
Unique_ptr(Unique_ptr< T, A > const &rhs)=delete
Unique_ptr()
Default class constructor, only to be used with no specific allocator.
Definition: unique_ptr.h:547
size_t m_size
The size of the allocated memory.
Definition: unique_ptr.h:346
typename std::remove_extent< T >::type type
Definition: unique_ptr.h:154
void destroy()
Deallocates the underlying allocated memory.
Definition: unique_ptr.h:724
pointer m_underlying
The pointer to the underlying allocated memory
Definition: unique_ptr.h:342
type & reference
Definition: unique_ptr.h:156
pointer release()
Releases the ownership of the underlying allocated memory and returns a pointer to the beginning of t...
type * pointer
Definition: unique_ptr.h:155
reference operator*() const
Star operator to access the underlying object of type T.
Definition: unique_ptr.h:620
void reset()
Clears the underlying pointer and size.
Definition: unique_ptr.h:715
const char * p
Definition: ctype-mb.cc:1237
#define U
Definition: ctype-tis620.cc:75
Fido Client Authentication nullptr
Definition: fido_client_plugin.cc:222
#define ME_FATALERROR
Definition: my_sys.h:152
#define MY_WME
Definition: my_sys.h:123
unsigned int PSI_memory_key
Instrumented memory key.
Definition: psi_memory_bits.h:49
#define MYF(v)
Definition: my_inttypes.h:97
void * my_malloc(PSI_memory_key key, size_t size, int flags)
Allocates size bytes of memory.
Definition: my_memory.cc:57
void my_free(void *ptr)
Frees the memory pointed by the ptr.
Definition: my_memory.cc:81
Common header for many mysys elements.
std::string HARNESS_EXPORT reset()
get 'reset attributes' ESC sequence.
Definition: vt100.cc:37
auto test_for_allocate(int T::*) -> decltype(std::declval< T >().allocate(std::declval< size_t >()), std::true_type{})
Tests for the existence of allocate(size_t) in order to disambiguate if T is an allocator class.
Definition: aligned_atomic.h:44
Unique_ptr< T, std::nullptr_t > make_unique(size_t size)
In-place constructs a new unique pointer with no specific allocator and with array type T.
static int destroy(mysql_cond_t *that, const char *, unsigned int)
Definition: mysql_cond_v1_native.cc:54
Definition: gcs_xcom_synode.h:64
required string key
Definition: replication_asynchronous_connection_failover.proto:60
required string type
Definition: replication_group_member_actions.proto:34
bool operator!=(const memory::PFS_allocator< T > &lhs, const memory::PFS_allocator< U > &rhs)
Definition: unique_ptr.h:454
bool operator==(const memory::PFS_allocator< T > &lhs, const memory::PFS_allocator< U > &rhs)
Definition: unique_ptr.h:448
Struct that allows for checking if T fulfills the Allocator named requirements.
Definition: unique_ptr.h:62
static ORDER * clone(THD *thd, ORDER *order)
Shallow clone the list of ORDER objects using mem_root and return the cloned list.
Definition: window.cc:84
int n
Definition: xcom_base.cc:509