43 template <typename T, bool = std::is_class<T>::value>
50 operator T&() noexcept {
return t; }
51 operator const T&()
const noexcept {
return t; }
60 #if __cpp_nontype_template_parameter_auto
61 template <auto FunPtr>
62 struct fun_ptr_deleter;
64 template <
typename Arg,
void (*FunPtr)(Arg)>
65 struct fun_ptr_deleter<FunPtr> {
66 auto operator()(Arg arg)
const ->
void {
return FunPtr(arg); }
70 namespace detail_memory {
72 template <
typename D,
typename T,
typename V =
void>
77 template <
typename D,
typename T>
79 using type =
typename std::remove_reference<D>::type::pointer;
82 template <
typename D,
typename T>
86 bool = std::is_class<T>::value and not std::is_final<T>::value,
88 = std::is_object<typename std::remove_reference<T>::type>::value>
94 auto base() noexcept -> T& {
return base_; }
95 auto base() const noexcept -> const T& {
return base_; }
96 explicit operator T&() noexcept {
return base(); }
97 explicit operator const T&()
const noexcept {
return base(); }
100 template <
typename T>
102 auto base() noexcept -> T& {
return *
this; }
103 auto base() const noexcept -> const T& {
return *
this; }
107 template <
typename R,
typename A,
bool E>
111 auto base() const noexcept ->
type& {
return *base_; }
112 explicit operator type&()
const noexcept {
return base(); }
115 template <
typename R,
typename A>
116 struct as_base_class<R (&)(A),
false,
false> {
119 auto base() const noexcept -> type& {
return *base_; }
120 explicit operator type&()
const noexcept {
return base(); }
124 template <
typename T>
128 auto base() noexcept -> T& {
return base_; }
129 auto base() const noexcept -> const T& {
return base_; }
131 explicit operator T&() noexcept {
return base(); }
132 explicit operator const T&()
const noexcept {
return base(); }
140 template <
typename T,
typename Construct = noop_t,
typename Destroy = noop_t>
142 template <
typename... Args>
147 template <
typename T,
typename D>
153 std::is_nothrow_copy_constructible<T>::value and
154 std::is_nothrow_copy_constructible<D>::value)
157 std::is_nothrow_move_constructible<T>::value and
158 std::is_nothrow_move_constructible<D>::value)
161 std::is_nothrow_copy_assignable<T>::value and
162 std::is_nothrow_copy_assignable<D>::value)
165 std::is_nothrow_move_assignable<T>::value and
166 std::is_nothrow_move_assignable<D>::value)
170 operator T&() noexcept {
return base(); }
171 operator const T&()
const noexcept {
return base(); }
174 (
invoke)(
static_cast<D&&
>(*
this),
static_cast<T&&
>(*this));
180 template <
typename T>
183 template <
typename T>
193 auto operator()(std::vector<live_wrapper**>&&
self) const noexcept
195 for (
auto p :
self) {
208 template <
typename T>
211 namespace detail_memory {
213 template <
typename T>
215 template <
template <
typename T>
class C,
typename T>
220 template <
typename D>
224 using mT =
typename std::remove_const<T>::type;
233 operator bool() const noexcept {
return obj; }
235 friend auto operator==(
const D& lhs, std::nullptr_t) ->
bool {
238 friend auto operator==(std::nullptr_t,
const D& rhs) ->
bool {
243 return lhs.obj == rhs.obj;
247 if (not lhs and not rhs) {
250 return lhs and &lhs.obj->data == rhs;
254 if (not rhs and not lhs) {
257 return rhs and &rhs.obj->data == lhs;
313 auto as_D() noexcept -> D& {
return static_cast<D&
>(*this); }
314 auto as_D() const noexcept -> const D& {
315 return static_cast<const D&
>(*this);
320 template <
typename T>
350 template <
typename mT>
392 template <
typename T>
397 template <
typename T>
402 template <
typename T>
411 template <
typename T,
typename Deleter = std::default_delete<T>>
421 static_assert(std::is_nothrow_invocable<Deleter&, pointer>::value,
422 "cond_ptr<T> requires that get_deleter not throw exceptions.");
425 using unique = std::unique_ptr<T, Deleter>;
431 std::decay_t<Deleter> del = {}) noexcept
432 : d_base{std::move(del)}
435 explicit cond_ptr(T* p, std::decay_t<Deleter> del) noexcept
448 :
d_base{other.get_deleter()}
457 return {p,
true, del};
474 static_cast<d_base&
>(*this) = {std::move(rhs.get_deleter())};
475 ptr_ = rhs.release();
479 static_cast<d_base&
>(*this) = {std::move(rhs.get_deleter())};
480 ptr_ = rhs.release();
504 return std::move(*this).to_unique();
508 if (owns_ and ptr_) {
524 return this->d_base::base();
528 return this->d_base::base();
531 auto reset(T* p =
nullptr,
bool owner =
false,
532 std::decay_t<Deleter> del = {}) & noexcept ->
void {
540 auto reset(T* p, std::decay_t<Deleter> del = {}) & noexcept ->
void {
552 swap(ptr_, other.ptr_);
553 swap(owns_, other.owns_);
577 return lhs.ptr_ == rhs.ptr_;
582 return lhs.get() == rhs.ptr_;
586 const unique& rhs) noexcept
588 return lhs.ptr_ == rhs.get();
596 template <
typename T,
typename Deleter>
606 static_assert(std::is_nothrow_invocable<Deleter&, pointer>::value,
607 "cond_ptr<T[]> requires that deleter not throw exceptions.");
610 using unique = std::unique_ptr<T[], Deleter>;
616 std::decay_t<Deleter> del = {}) noexcept
617 : d_base{std::move(del)}
620 explicit cond_ptr(T* p, std::decay_t<Deleter> del) noexcept
633 :
d_base{other.get_deleter()}
642 return {p,
true, del};
659 ptr_ = rhs.release();
663 ptr_ = rhs.release();
688 return std::move(*this).to_unique();
713 auto reset(T* p =
nullptr,
bool owner =
false,
714 std::decay_t<Deleter> del = {}) & noexcept ->
void {
722 auto reset(T* p, std::decay_t<Deleter> del = {}) & noexcept ->
void {
741 explicit operator bool() const noexcept {
return ptr_; }
753 return lhs.ptr_ == rhs.ptr_;
758 return lhs.get() == rhs.ptr_;
762 const unique& rhs) noexcept
764 return lhs.ptr_ == rhs.get();
772 template <
typename T,
typename Deleter>
778 template <
typename T>
784 template <
typename T,
typename Deleter>
790 template <
typename T,
typename Deleter>
Provides general-purpose algorithms, similar to the <algorithms> header.
cond_ptr(cond_ptr &&other) noexcept
auto get_deleter() const noexcept -> const Deleter &
auto release() &noexcept -> T *
static auto adopt(T *p, deleter_type del) noexcept -> cond_ptr
auto operator=(unique &&rhs) -> cond_ptr &
auto swap(cond_ptr &other) -> void
cond_ptr(T *p, std::decay_t< Deleter > del) noexcept
detail_memory::filter_deleter_pointer_t< Deleter, T > pointer
auto get_deleter() noexcept -> Deleter &
cond_ptr() noexcept=default
auto operator=(cond_ptr &&rhs) &noexcept -> cond_ptr &
T & operator[](std::size_t index) &noexcept
cond_ptr(unique &&p) noexcept
std::unique_ptr< T[], Deleter > unique
const T & operator[](std::size_t index) const &noexcept
auto get() &noexcept -> T *
auto to_unique() &&noexcept -> unique
Transfers ownership to a unique_ptr if possible. If *this is not owning, returns nullptr.
auto reset(T *p=nullptr, bool owner=false, std::decay_t< Deleter > del={}) &noexcept -> void
constexpr friend auto operator==(const unique &lhs, const cond_ptr &rhs) noexcept -> bool
auto weak() const &noexcept -> cond_ptr
constexpr friend auto operator==(const cond_ptr &lhs, const unique &rhs) noexcept -> bool
static auto adopt(T *p) noexcept -> cond_ptr
auto reset(T *p, std::decay_t< Deleter > del={}) &noexcept -> void
constexpr friend auto operator==(const cond_ptr &lhs, const cond_ptr &rhs) noexcept -> bool
auto get() const &noexcept -> const T *
cond_ptr(const cond_ptr &other)=delete
cond_ptr(T *p, bool owner=false, std::decay_t< Deleter > del={}) noexcept
auto owns() const noexcept -> bool
auto operator=(const cond_ptr &rhs) &-> cond_ptr &=delete
auto operator=(const cond_ptr &rhs) &-> cond_ptr &=delete
static auto adopt(T *p, deleter_type del) noexcept -> cond_ptr
auto reset(T *p=nullptr, bool owner=false, std::decay_t< Deleter > del={}) &noexcept -> void
auto operator*() const &noexcept -> const T &
auto operator->() &noexcept -> T *
auto operator*() &noexcept -> T &
auto release() &noexcept -> T *
std::unique_ptr< T, Deleter > unique
auto owns() const noexcept -> bool
cond_ptr(T *p, bool owner=false, std::decay_t< Deleter > del={}) noexcept
auto swap(cond_ptr &other) noexcept(fakestd::is_nothrow_swappable< Deleter >::value) -> void
cond_ptr(T *p, std::decay_t< Deleter > del) noexcept
auto get() &noexcept -> T *
cond_ptr(const cond_ptr &other)=delete
auto get_deleter() noexcept -> Deleter &
auto operator=(unique &&rhs) -> cond_ptr &
auto operator=(cond_ptr &&rhs) &noexcept -> cond_ptr &
auto get_deleter() const noexcept -> const Deleter &
cond_ptr(unique &&p) noexcept
auto get() const &noexcept -> const T *
cond_ptr() noexcept=default
constexpr friend auto operator==(const unique &lhs, const cond_ptr &rhs) noexcept -> bool
auto to_unique() &&noexcept -> unique
Transfers ownership to a unique_ptr if possible. If *this is not owning, returns nullptr.
static auto adopt(T *p) noexcept -> cond_ptr
auto operator->() const &noexcept -> const T *
constexpr friend auto operator==(const cond_ptr &lhs, const unique &rhs) noexcept -> bool
constexpr friend auto operator==(const cond_ptr &lhs, const cond_ptr &rhs) noexcept -> bool
auto weak() const &noexcept -> cond_ptr
detail_memory::filter_deleter_pointer_t< Deleter, T > pointer
auto reset(T *p, std::decay_t< Deleter > del={}) &noexcept -> void
cond_ptr(cond_ptr &&other) noexcept
auto operator=(const live_ptr< mT > &o) -> live_ptr &
live_ptr(const live_ptr< T > &o)=default
auto operator=(const live_ptr< T > &o) -> live_ptr &=default
auto operator=(live_ptr< T > &&o) noexcept -> live_ptr &=default
live_ptr(const live_ptr< mT > &o)
live_ptr(live_ptr< mT > &&o) noexcept
live_ptr(const live_wrapper< mT > &o)
auto operator=(live_ptr< mT > &&o) noexcept -> live_ptr &
live_ptr(live_ptr< T > &&o) noexcept=default
auto operator=(const live_wrapper< mT > &o) -> live_ptr &
auto operator=(live_ptr &&o) noexcept -> live_ptr &=default
auto operator=(live_wrapper< T > &o) -> live_ptr &
live_ptr(live_ptr &&o) noexcept=default
live_ptr(const live_ptr &o)=default
auto operator=(const live_ptr &o) -> live_ptr &=default
live_ptr(live_wrapper< T > &o)
live_ptr< const T > cref() const
live_ptr< const T > ref() const
null_construct< detail_memory::on_destroy< std::vector< live_wrapper ** >, _destroy > > _observers
typename filter_deleter_pointer< D, T >::type filter_deleter_pointer_t
typename make_void< Ts... >::type void_t
The main namespace in which all entities from kblib are defined.
constexpr auto exchange(T &obj, U &&new_value) -> T
constexpr auto invoke(F &&f, Args &&... args) noexcept(noexcept(detail::do_invoke(std::forward< F >(f), std::forward< Args >(args)...))) -> decltype(auto)
constexpr auto erase(Container &c, const Elem &val) noexcept(noexcept(c.erase(std::remove(c.begin(), c.end(), val), c.end()))) -> void
Abbreviation of the erase-remove idiom as a free function.
auto make_cond_ptr(std::unique_ptr< T, Deleter > &&arg) noexcept -> cond_ptr< T, Deleter >
auto base() const noexcept -> type &
auto base() const noexcept -> const T &
auto base() noexcept -> T &
auto base() const noexcept -> const T &
auto base() noexcept -> T &
std::reference_wrapper< T > base_
auto base() const noexcept -> const T &
auto base() noexcept -> T &
typename std::remove_reference< D >::type::pointer type
auto operator->() const noexcept -> const T *
friend auto operator==(const T *lhs, const D &rhs) -> bool
auto operator->() noexcept -> T *
live_ptr_base() noexcept=default
friend auto operator==(const D &lhs, const D &rhs) -> bool
live_ptr_base(const live_ptr_base &o)
auto operator=(D &&o) noexcept -> D &
friend auto operator==(std::nullptr_t, const D &rhs) -> bool
auto operator=(live_ptr_base &&o) noexcept -> live_ptr_base &
auto operator*() const noexcept -> const T &
auto operator=(const live_ptr_base &o) noexcept -> live_ptr_base &
auto operator=(const D &o) -> D &
friend auto operator==(const D &lhs, const T *rhs) -> bool
friend auto operator==(const D &lhs, std::nullptr_t) -> bool
auto operator*() noexcept -> T &
live_ptr_base(live_ptr_base &&o) noexcept
auto operator()() const noexcept -> void
on_destroy() noexcept=default
rule_zero(Args &&... args)
auto operator()(std::vector< live_wrapper ** > &&self) const noexcept -> void
null_construct() noexcept(std::is_nothrow_default_constructible< T >::value)
null_construct() noexcept(std::is_nothrow_default_constructible< T >::value)
Provides macros and basic templates used by the rest of kblib.
#define KBLIB_NODISCARD
This internal macro is used to provide a fallback for [[nodiscard]] in C++14.