37 using internal_pointer = std::unique_ptr<T>;
42 using pointer =
typename internal_pointer::pointer;
64 constexpr
void reset() noexcept;
68 [[nodiscard]] constexpr T*
get() noexcept;
69 [[nodiscard]] constexpr const T*
get() const noexcept;
71 constexpr explicit operator
bool() const noexcept;
72 [[nodiscard]] constexpr
bool has_value() const noexcept;
74 [[nodiscard]] constexpr T& operator*();
75 [[nodiscard]] constexpr const T& operator*() const;
77 [[nodiscard]] constexpr T* operator->();
78 [[nodiscard]] constexpr const T* operator->() const;
82 internal_pointer value_;
92 template <
class T,
class D>
109 concept clonable = std::derived_from<T, std::decay_t<decltype(*std::declval<T*>()->clone())>>
124 template <clonable T>
127 using internal_pointer = std::unique_ptr<T>;
131 using self_type = cloning_ptr<T>;
132 using pointer =
typename internal_pointer::pointer;
133 using element_type =
typename internal_pointer::element_type;
137 constexpr cloning_ptr()
noexcept =
default;
138 constexpr cloning_ptr(std::nullptr_t)
noexcept;
139 explicit constexpr cloning_ptr(pointer p)
noexcept;
141 constexpr ~cloning_ptr() =
default;
143 constexpr cloning_ptr(
const self_type& rhs)
noexcept;
144 constexpr cloning_ptr(self_type&& rhs)
noexcept =
default;
147 template <clonable U>
148 requires std::convertible_to<U*, T*>
149 constexpr cloning_ptr(
const cloning_ptr<U>& rhs)
noexcept;
151 template <clonable U>
152 requires std::convertible_to<U*, T*>
153 constexpr cloning_ptr(cloning_ptr<U>&& rhs)
noexcept;
155 constexpr self_type& operator=(
const self_type&)
noexcept;
156 constexpr self_type& operator=(self_type&&)
noexcept =
default;
157 constexpr self_type& operator=(std::nullptr_t)
noexcept;
159 template <clonable U>
160 requires std::convertible_to<U*, T*>
161 constexpr self_type& operator=(
const cloning_ptr<U>& rhs)
noexcept;
163 template <clonable U>
164 requires std::convertible_to<U*, T*>
165 constexpr self_type& operator=(cloning_ptr<U>&& rhs)
noexcept;
169 constexpr pointer release()
noexcept;
170 constexpr void reset(pointer ptr = pointer())
noexcept;
171 void swap(self_type&)
noexcept;
175 [[nodiscard]]
constexpr pointer get()
const noexcept;
177 constexpr explicit operator bool()
const noexcept;
179 [[nodiscard]]
constexpr std::add_lvalue_reference_t<T>
180 operator*()
const noexcept(
noexcept(*std::declval<pointer>()));
182 [[nodiscard]]
constexpr pointer operator->()
const noexcept;
186 [[nodiscard]]
constexpr internal_pointer& ptr_impl()
noexcept;
187 [[nodiscard]]
constexpr const internal_pointer& ptr_impl()
const noexcept;
189 internal_pointer m_data;
193 void swap(cloning_ptr<T>& lhs, cloning_ptr<T>& rhs)
noexcept;
195 template <
class T1,
class T2>
196 requires std::equality_comparable_with<typename cloning_ptr<T1>::pointer,
typename cloning_ptr<T2>::pointer>
197 constexpr bool operator==(
const cloning_ptr<T1>& lhs,
const cloning_ptr<T2>& rhs)
noexcept;
199 template <
class T1,
class T2>
200 requires std::three_way_comparable_with<typename cloning_ptr<T1>::pointer,
typename cloning_ptr<T2>::pointer>
201 constexpr std::compare_three_way_result_t<typename cloning_ptr<T1>::pointer,
typename cloning_ptr<T2>::pointer>
202 operator<=>(
const cloning_ptr<T1>& lhs,
const cloning_ptr<T2>& rhs)
noexcept;
205 constexpr bool operator==(
const cloning_ptr<T>& lhs, std::nullptr_t)
noexcept;
208 requires std::three_way_comparable<typename cloning_ptr<T>::pointer>
209 constexpr std::compare_three_way_result_t<typename cloning_ptr<T>::pointer>
210 operator<=>(
const cloning_ptr<T>& lhs, std::nullptr_t)
noexcept;
212 template <
class T,
class... Args>
226 : value_(
std::make_unique<T>(
std::move(value)))
232 : value_(value != nullptr ?
std::make_unique<T>(*value) :
std::unique_ptr<T>())
238 : value_(other.value_ ?
std::make_unique<T>(*other.value_) :
std::unique_ptr<T>())
249 *value_ = *other.value_;
253 value_ = std::make_unique<T>(*other.value_);
332 template <clonable T>
333 constexpr cloning_ptr<T>::cloning_ptr(std::nullptr_t) noexcept
338 template <clonable T>
339 constexpr cloning_ptr<T>::cloning_ptr(pointer p) noexcept
344 template <clonable T>
345 constexpr cloning_ptr<T>::cloning_ptr(
const cloning_ptr& rhs) noexcept
346 : m_data(rhs ? rhs->clone() :
nullptr)
350 template <clonable T>
351 template <clonable U>
352 requires std::convertible_to<U*, T*>
353 constexpr cloning_ptr<T>::cloning_ptr(
const cloning_ptr<U>& rhs) noexcept
354 : m_data(rhs ? rhs->clone() :
nullptr)
358 template <clonable T>
359 template <clonable U>
360 requires std::convertible_to<U*, T*>
361 constexpr cloning_ptr<T>::cloning_ptr(cloning_ptr<U>&& rhs) noexcept
362 : m_data(rhs.release())
366 template <clonable T>
367 constexpr auto cloning_ptr<T>::operator=(
const self_type& rhs)
noexcept -> self_type&
369 m_data = rhs ? rhs->clone() :
nullptr;
373 template <clonable T>
374 constexpr auto cloning_ptr<T>::operator=(std::nullptr_t)
noexcept -> self_type&
380 template <clonable T>
381 template <clonable U>
382 requires std::convertible_to<U*, T*>
383 constexpr auto cloning_ptr<T>::operator=(
const cloning_ptr<U>& rhs)
noexcept -> self_type&
385 m_data = rhs ? rhs->clone() :
nullptr;
389 template <clonable T>
390 template <clonable U>
391 requires std::convertible_to<U*, T*>
392 constexpr auto cloning_ptr<T>::operator=(cloning_ptr<U>&& rhs)
noexcept -> self_type&
394 reset(rhs.release());
398 template <clonable T>
399 constexpr auto cloning_ptr<T>::release() noexcept -> pointer
401 return ptr_impl().release();
404 template <clonable T>
405 constexpr void cloning_ptr<T>::reset(pointer ptr)
noexcept
407 ptr_impl().reset(ptr);
410 template <clonable T>
411 void cloning_ptr<T>::swap(self_type& other)
noexcept
414 swap(ptr_impl(), other.ptr_impl());
417 template <clonable T>
418 constexpr auto cloning_ptr<T>::get() const noexcept -> pointer
420 return ptr_impl().get();
423 template <clonable T>
424 constexpr cloning_ptr<T>::operator bool() const noexcept
426 return bool(ptr_impl());
429 template <clonable T>
430 constexpr std::add_lvalue_reference_t<T>
431 cloning_ptr<T>::operator*() const noexcept(noexcept(*std::declval<pointer>()))
436 template <clonable T>
437 constexpr auto cloning_ptr<T>::operator->() const noexcept -> pointer
442 template <clonable T>
443 constexpr auto cloning_ptr<T>::ptr_impl() noexcept -> internal_pointer&
448 template <clonable T>
449 constexpr auto cloning_ptr<T>::ptr_impl() const noexcept -> const internal_pointer&
459 void swap(cloning_ptr<T>& lhs, cloning_ptr<T>& rhs)
noexcept
464 template <
class T1,
class T2>
465 requires std::equality_comparable_with<typename cloning_ptr<T1>::pointer,
typename cloning_ptr<T2>::pointer>
466 constexpr bool operator==(
const cloning_ptr<T1>& lhs,
const cloning_ptr<T2>& rhs)
noexcept
468 return lhs.get() == rhs.get();
471 template <
class T1,
class T2>
472 requires std::three_way_comparable_with<typename cloning_ptr<T1>::pointer,
typename cloning_ptr<T2>::pointer>
473 constexpr std::compare_three_way_result_t<typename cloning_ptr<T1>::pointer,
typename cloning_ptr<T2>::pointer>
474 operator<=>(
const cloning_ptr<T1>& lhs,
const cloning_ptr<T2>& rhs)
noexcept
476 return lhs.get() <=> rhs.get();
480 constexpr bool operator==(
const cloning_ptr<T>& lhs, std::nullptr_t)
noexcept
486 requires std::three_way_comparable<typename cloning_ptr<T>::pointer>
487 constexpr std::compare_three_way_result_t<typename cloning_ptr<T>::pointer>
488 operator<=>(
const cloning_ptr<T>& lhs, std::nullptr_t)
noexcept
490 using pointer =
typename cloning_ptr<T>::pointer;
491 return lhs.get() <=>
static_cast<pointer
>(
nullptr);
494 template <
class T,
class... Args>
497 return cloning_ptr<T>(
new T(std::forward<Args>(args)...));
constexpr bool has_value() const noexcept
constexpr T * get() noexcept
typename internal_pointer::element_type element_type
typename internal_pointer::pointer pointer
constexpr value_ptr & operator=(const value_ptr &other)
constexpr T & operator*()
constexpr void reset() noexcept
constexpr T * operator->()
constexpr value_ptr() noexcept=default
Matches types that provide a clone method.
#define SPARROW_ASSERT_TRUE(expr__)
SPARROW_API void reset(const std::string &key)
constexpr bool is_unique_ptr_v
constexpr std::compare_three_way_result_t< typename cloning_ptr< T1 >::pointer, typename cloning_ptr< T2 >::pointer > operator<=>(const cloning_ptr< T1 > &lhs, const cloning_ptr< T2 > &rhs) noexcept
SPARROW_API bool operator==(const array &lhs, const array &rhs)
Compares the content of two arrays.
cloning_ptr< T > make_cloning_ptr(Args &&... args)
SPARROW_API void swap(ArrowArray &lhs, ArrowArray &rhs) noexcept
Swaps the contents of the two ArrowArray objects.
Extensions to the C++ standard library.