43template <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
62struct fun_ptr_deleter;
64template <
typename Arg,
void (*FunPtr)(Arg)>
65struct fun_ptr_deleter<FunPtr> {
66 auto operator()(Arg arg)
const ->
void {
return FunPtr(arg); }
70namespace 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; }
108 noexcept(
std::is_nothrow_copy_constructible<T>::value)
112 noexcept(
std::is_nothrow_move_constructible<T>::value)
117 template <
typename R,
typename A,
bool E>
121 auto base() const noexcept ->
type& {
return *base_; }
122 explicit operator type&()
const noexcept {
return base(); }
125 template <
typename R,
typename A>
126 struct as_base_class<R (&)(A),
false,
false> {
129 auto base() const noexcept -> type& {
return *base_; }
130 explicit operator type&()
const noexcept {
return base(); }
134 template <
typename T>
138 auto base() noexcept -> T& {
return base_; }
139 auto base() const noexcept -> const T& {
return base_; }
141 explicit operator T&()
noexcept {
return base(); }
142 explicit operator const T&()
const noexcept {
return base(); }
150 template <
typename T,
typename Construct = noop_t,
typename Destroy = noop_t>
152 template <
typename... Args>
157 template <
typename T,
typename D>
163 std::is_nothrow_copy_constructible<T>::value and
164 std::is_nothrow_copy_constructible<D>::value)
167 std::is_nothrow_move_constructible<T>::value and
168 std::is_nothrow_move_constructible<D>::value)
171 std::is_nothrow_copy_assignable<T>::value and
172 std::is_nothrow_copy_assignable<D>::value)
175 std::is_nothrow_move_assignable<T>::value and
176 std::is_nothrow_move_assignable<D>::value)
180 operator T&() noexcept {
return base(); }
181 operator const T&()
const noexcept {
return base(); }
184 (
invoke)(
static_cast<D&&
>(*
this),
static_cast<T&&
>(*this));
203 auto operator()(std::vector<live_wrapper**>&& self)
const noexcept
205 for (
auto p : self) {
221namespace detail_memory {
223 template <
typename T>
225 template <
template <
typename T>
class C,
typename T>
230 template <
typename D>
234 using mT =
typename std::remove_const<T>::type;
238 auto operator*() const noexcept -> const T& {
return obj->data; }
241 auto operator->() const noexcept -> const T* {
return &obj->data; }
243 operator bool() const noexcept {
return obj; }
245 friend auto operator==(
const D& lhs, std::nullptr_t) ->
bool {
248 friend auto operator==(std::nullptr_t,
const D& rhs) ->
bool {
253 return lhs.obj == rhs.obj;
257 if (not lhs and not rhs) {
260 return lhs and &lhs.obj->data == rhs;
264 if (not rhs and not lhs) {
267 return rhs and &rhs.obj->data == lhs;
308 auto add() ->
void { obj->_observers.base().push_back(&obj); }
311 erase(obj->_observers.base(), &obj);
316 std::replace(obj->_observers.base().begin(),
317 obj->_observers.base().end(), &o.obj, &obj);
323 auto as_D() noexcept -> D& {
return static_cast<D&
>(*this); }
324 auto as_D() const noexcept -> const D& {
325 return static_cast<const D&
>(*this);
360template <
typename mT>
421template <
typename T,
typename Deleter = std::default_delete<T>>
431 static_assert(std::is_nothrow_invocable<Deleter&, pointer>::value,
432 "cond_ptr<T> requires that get_deleter not throw exceptions.");
435 using unique = std::unique_ptr<T, Deleter>;
441 std::decay_t<Deleter> del = {})
noexcept
442 : d_base{std::move(del)}
445 explicit cond_ptr(T* p, std::decay_t<Deleter> del) noexcept
458 :
d_base{other.get_deleter()}
467 return {p,
true, del};
484 static_cast<d_base&
>(*this) = {std::move(rhs.get_deleter())};
485 ptr_ = rhs.release();
489 static_cast<d_base&
>(*this) = {std::move(rhs.get_deleter())};
490 ptr_ = rhs.release();
507 return {release(), std::move(get_deleter())};
509 return {
nullptr, get_deleter()};
514 return std::move(*this).to_unique();
518 if (owns_ and ptr_) {
534 return this->d_base::base();
538 return this->d_base::base();
542 std::decay_t<Deleter> del = {}) &
noexcept ->
void {
548 get_deleter() = std::move(del);
550 auto reset(T* p, std::decay_t<Deleter> del = {}) &
noexcept ->
void {
556 get_deleter() = std::move(del);
562 swap(ptr_, other.ptr_);
563 swap(owns_, other.owns_);
564 swap(get_deleter(), other.get_deleter());
587 return lhs.ptr_ == rhs.ptr_;
592 return lhs.get() == rhs.ptr_;
596 const unique& rhs)
noexcept
598 return lhs.ptr_ == rhs.get();
606template <
typename T,
typename Deleter>
616 static_assert(std::is_nothrow_invocable<Deleter&, pointer>::value,
617 "cond_ptr<T[]> requires that deleter not throw exceptions.");
620 using unique = std::unique_ptr<T[], Deleter>;
626 std::decay_t<Deleter> del = {})
noexcept
627 : d_base{std::move(del)}
630 explicit cond_ptr(T* p, std::decay_t<Deleter> del) noexcept
643 :
d_base{other.get_deleter()}
652 return {p,
true, del};
669 ptr_ = rhs.release();
675 get_deleter() = std::move(rhs.get_deleter());
691 return {release(), get_deleter()};
698 return std::move(*this).to_unique();
724 std::decay_t<Deleter> del = {}) &
noexcept ->
void {
730 get_deleter() = std::move(del);
732 auto reset(T* p, std::decay_t<Deleter> del = {}) &
noexcept ->
void {
738 get_deleter() = std::move(del);
744 std::swap(get_deleter(), other.get_deleter());
751 explicit operator bool() const noexcept {
return ptr_; }
763 return lhs.ptr_ == rhs.ptr_;
768 return lhs.get() == rhs.ptr_;
772 const unique& rhs)
noexcept
774 return lhs.ptr_ == rhs.get();
782template <
typename T,
typename Deleter>
794template <
typename T,
typename Deleter>
800template <
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 &
const T & operator[](std::size_t index) const &noexcept
T & operator[](std::size_t index) &noexcept
cond_ptr() noexcept=default
auto operator=(cond_ptr &&rhs) &noexcept -> cond_ptr &
cond_ptr(unique &&p) noexcept
std::unique_ptr< T[], Deleter > unique
auto get() &noexcept -> T *
auto to_unique() &&noexcept -> unique
Transfers ownership to a unique_ptr if possible. If *this is not owning, returns nullptr.
friend constexpr auto operator==(const unique &lhs, const cond_ptr &rhs) noexcept -> bool
auto reset(T *p=nullptr, bool owner=false, std::decay_t< Deleter > del={}) &noexcept -> void
auto weak() const &noexcept -> cond_ptr
static auto adopt(T *p) noexcept -> cond_ptr
auto reset(T *p, std::decay_t< Deleter > del={}) &noexcept -> void
friend constexpr auto operator==(const cond_ptr &lhs, const unique &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
friend constexpr auto operator==(const cond_ptr &lhs, const cond_ptr &rhs) 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 &
friend constexpr auto operator==(const unique &lhs, const cond_ptr &rhs) noexcept -> bool
cond_ptr(unique &&p) noexcept
auto get() const &noexcept -> const T *
cond_ptr() noexcept=default
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 *
auto weak() const &noexcept -> cond_ptr
detail_memory::filter_deleter_pointer_t< Deleter, T > pointer
friend constexpr auto operator==(const cond_ptr &lhs, const unique &rhs) noexcept -> bool
friend constexpr auto operator==(const cond_ptr &lhs, const cond_ptr &rhs) noexcept -> bool
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
typename filter_deleter_pointer< D, T >::type filter_deleter_pointer_t
typename make_void< Ts... >::type void_t
constexpr auto exchange(T &obj, U &&new_value) -> T
typename std::enable_if< B, T >::type enable_if_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(T *arg, bool owner, Deleter del) noexcept -> cond_ptr< T, Deleter >
auto base() const noexcept -> type &
auto base() const noexcept -> const T &
auto base() noexcept -> T &
as_base_class(T &&t, enable_if_t< std::is_move_constructible< T >::value, as_base_class * >=nullptr) noexcept(std::is_nothrow_move_constructible< T >::value)
auto base() const noexcept -> const T &
as_base_class(const T &t, enable_if_t< std::is_copy_constructible< T >::value, as_base_class * >=nullptr) noexcept(std::is_nothrow_copy_constructible< T >::value)
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.