Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
382 changes: 153 additions & 229 deletions doc/rvariant.adoc

Large diffs are not rendered by default.

466 changes: 165 additions & 301 deletions doc/rvariant.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion include/iris/hash_fwd.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

#include <version>

#if __cplusplus <= 202302L || \
#if !defined(_MSC_VER) && __cplusplus <= 202302L || \
(defined(_MSVC_STL_UPDATE) && _MSVC_STL_UPDATE < 202504L) || \
(defined(__GLIBCXX__) && __GLIBCXX__ < 20241201) || \
(defined(_LIBCPP_STD_VER) && _LIBCPP_STD_VER < 26)
Expand Down
45 changes: 22 additions & 23 deletions include/iris/indirect.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@

// SPDX-License-Identifier: MIT

#include <iris/bits/specialization_of.hpp>
#include <iris/compare.hpp>
#include <iris/hash.hpp>
#include <iris/type_traits.hpp>

#include <compare>
#include <memory>
Expand All @@ -25,13 +25,12 @@ class scoped_allocation
using pointer = std::allocator_traits<Alloc>::pointer;
using const_pointer = std::allocator_traits<Alloc>::const_pointer;


template<class... Args>
constexpr explicit scoped_allocation(Alloc const& a, std::in_place_t, Args&&... args)
constexpr explicit scoped_allocation(Alloc const& a, Args&&... args)
: alloc_(a)
, ptr_(std::allocator_traits<Alloc>::allocate(alloc_, 1))
{
std::allocator_traits<Alloc>::construct(alloc_, get(), std::forward<Args>(args)...);
std::allocator_traits<Alloc>::construct(alloc_, this->get(), std::forward<Args>(args)...);
}

constexpr ~scoped_allocation()
Expand Down Expand Up @@ -70,7 +69,7 @@ class indirect_base
using const_pointer = std::allocator_traits<Allocator>::const_pointer;

constexpr explicit indirect_base() requires std::is_default_constructible_v<Allocator>
: ptr_(make_obj())
: ptr_(this->make_obj())
{}

constexpr indirect_base(indirect_base const& other)
Expand All @@ -83,12 +82,12 @@ class indirect_base

constexpr explicit indirect_base(std::allocator_arg_t, Allocator const& a)
: alloc_(a)
, ptr_(make_obj())
, ptr_(this->make_obj())
{}

constexpr indirect_base(std::allocator_arg_t, Allocator const& a, indirect_base const& other)
: alloc_(a)
, ptr_(other.ptr_ ? make_obj(std::as_const(*other.ptr_)) : nullptr)
, ptr_(other.ptr_ ? this->make_obj(std::as_const(*other.ptr_)) : nullptr)
{
static_assert(std::is_copy_constructible_v<T>);
}
Expand All @@ -103,7 +102,7 @@ class indirect_base
: alloc_(a)
, ptr_(alloc_ == other.alloc_
? std::exchange(other.ptr_, nullptr)
: make_obj(*std::move(other))
: this->make_obj(*std::move(other))
)
{}

Expand All @@ -114,7 +113,7 @@ class indirect_base
std::is_constructible_v<T, U> &&
std::is_default_constructible_v<Allocator>
constexpr explicit indirect_base(U&& u)
: ptr_(make_obj(std::forward<U>(u)))
: ptr_(this->make_obj(std::forward<U>(u)))
{}

template<class U = T>
Expand All @@ -124,45 +123,45 @@ class indirect_base
std::is_constructible_v<T, U>
constexpr explicit indirect_base(std::allocator_arg_t, Allocator const& a, U&& u)
: alloc_(a)
, ptr_(make_obj(std::forward<U>(u)))
, ptr_(this->make_obj(std::forward<U>(u)))
{}

template<class... Us>
requires
std::is_constructible_v<T, Us...> &&
std::is_default_constructible_v<Allocator>
constexpr explicit indirect_base(std::in_place_t, Us&&... us)
: ptr_(make_obj(std::forward<Us>(us)...))
: ptr_(this->make_obj(std::forward<Us>(us)...))
{}

template<class... Us>
requires
std::is_constructible_v<T, Us...>
constexpr explicit indirect_base(std::allocator_arg_t, Allocator const& a, std::in_place_t, Us&&... us)
: alloc_(a)
, ptr_(make_obj(std::forward<Us>(us)...))
, ptr_(this->make_obj(std::forward<Us>(us)...))
{}

template<class I, class... Us>
requires
std::is_constructible_v<T, std::initializer_list<I>&, Us...> &&
std::is_default_constructible_v<Allocator>
constexpr explicit indirect_base(std::in_place_t, std::initializer_list<I> il, Us&&... us)
: ptr_(make_obj(il, std::forward<Us>(us)...))
: ptr_(this->make_obj(il, std::forward<Us>(us)...))
{}

template<class I, class... Us>
requires
std::is_constructible_v<T, std::initializer_list<I>&, Us...>
constexpr explicit indirect_base(std::allocator_arg_t, Allocator const& a, std::in_place_t, std::initializer_list<I> il, Us&&... us)
: alloc_(a)
, ptr_(make_obj(il, std::forward<Us>(us)...))
, ptr_(this->make_obj(il, std::forward<Us>(us)...))
{}

constexpr ~indirect_base() noexcept
{
if (ptr_) [[likely]] {
destroy_deallocate();
this->destroy_deallocate();
}
}

Expand Down Expand Up @@ -220,7 +219,7 @@ class indirect_base
// other.ptr_ && (ptr_ || !ptr_)
// either allocator is not equal or `this` does not contain value; create copy from `other`
if (ptr_) [[likely]] {
destroy_deallocate();
this->destroy_deallocate();
ptr_ = nullptr; // make it safer
}
if constexpr (pocca) {
Expand All @@ -234,7 +233,7 @@ class indirect_base

} else [[unlikely]] { // !other.ptr_
if (ptr_) [[likely]] {
destroy_deallocate();
this->destroy_deallocate();
ptr_ = nullptr; // make it safer
}
if constexpr (pocca) {
Expand All @@ -261,7 +260,7 @@ class indirect_base
if (other.ptr_) [[likely]] {
if constexpr (std::allocator_traits<Allocator>::is_always_equal::value) {
if (ptr_) [[likely]] {
destroy_deallocate();
this->destroy_deallocate();
}
ptr_ = std::exchange(other.ptr_, nullptr);
if constexpr (pocma) {
Expand All @@ -271,7 +270,7 @@ class indirect_base

} else if (alloc_ == other.alloc_) {
if (ptr_) [[likely]] {
destroy_deallocate();
this->destroy_deallocate();
}
ptr_ = std::exchange(other.ptr_, nullptr);
if constexpr (pocma) {
Expand All @@ -281,7 +280,7 @@ class indirect_base

} else {
if (ptr_) [[likely]] {
destroy_deallocate();
this->destroy_deallocate();
}
if constexpr (pocma) {
ptr_ = other.make_obj(std::move(*other));
Expand All @@ -293,7 +292,7 @@ class indirect_base
}
} else [[unlikely]] { // !other.ptr_
if (ptr_) [[likely]] {
destroy_deallocate();
this->destroy_deallocate();
ptr_ = nullptr;
}
if constexpr (pocma) {
Expand All @@ -314,7 +313,7 @@ class indirect_base
**this = std::forward<U>(u);

} else [[unlikely]] {
ptr_ = make_obj(std::forward<U>(u));
ptr_ = this->make_obj(std::forward<U>(u));
}
return *this;
}
Expand Down Expand Up @@ -361,7 +360,7 @@ class indirect_base
template<class... Args>
[[nodiscard]] constexpr T* make_obj(Args&&... args) const
{
detail::scoped_allocation sa(alloc_, std::in_place, std::forward<Args>(args)...);
detail::scoped_allocation sa(alloc_, std::forward<Args>(args)...);
return sa.release();
}

Expand Down
1 change: 0 additions & 1 deletion include/iris/requirements.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
#include <iris/bits/specialization_of.hpp>

#include <concepts>
#include <iosfwd>
#include <type_traits>
#include <utility>

Expand Down
16 changes: 11 additions & 5 deletions include/iris/rvariant/detail/recursive_traits.hpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
#ifndef IRIS_RVARIANT_DETAIL_RECURSIVE_TRAITS_HPP
#ifndef IRIS_RVARIANT_DETAIL_RECURSIVE_TRAITS_HPP
#define IRIS_RVARIANT_DETAIL_RECURSIVE_TRAITS_HPP

// SPDX-License-Identifier: MIT

// IWYU pragma: private, include <iris/rvariant.hpp>

#include <iris/rvariant/detail/rvariant_fwd.hpp>
#include <iris/type_traits.hpp>

namespace iris::detail {

Expand All @@ -20,10 +19,17 @@ struct select_maybe_wrapped_impl<false, I, U, U, Rest...>
static constexpr std::size_t index = I;
};

template<std::size_t I, class U, class... Rest>
struct select_maybe_wrapped_impl<false, I, U, recursive_wrapper<U>, Rest...>
{
using type = recursive_wrapper<U>;
static constexpr std::size_t index = I;
};

template<std::size_t I, class U, class Allocator, class... Rest>
struct select_maybe_wrapped_impl<false, I, U, recursive_wrapper<U, Allocator>, Rest...>
struct select_maybe_wrapped_impl<false, I, U, recursive_wrapper_alloca<U, Allocator>, Rest...>
{
using type = recursive_wrapper<U, Allocator>;
using type = recursive_wrapper_alloca<U, Allocator>;
static constexpr std::size_t index = I;
};

Expand All @@ -37,7 +43,7 @@ struct select_maybe_wrapped : select_maybe_wrapped_impl<false, 0, U, Ts...>
{
// Precondition: either T or recursive_wrapper<T> occurs at least once in Ts...
static_assert(sizeof...(Ts) > 0);
static_assert(!is_ttp_specialization_of_v<U, recursive_wrapper>);
static_assert(!detail::is_recursive_wrapper_like_v<U>);
};

template<class U, class... Ts>
Expand Down
7 changes: 5 additions & 2 deletions include/iris/rvariant/detail/rvariant_fwd.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#ifndef IRIS_RVARIANT_DETAIL_RVARIANT_FWD_HPP
#ifndef IRIS_RVARIANT_DETAIL_RVARIANT_FWD_HPP
#define IRIS_RVARIANT_DETAIL_RVARIANT_FWD_HPP

// SPDX-License-Identifier: MIT
Expand All @@ -20,9 +20,12 @@ namespace iris {
template<class... Ts>
class rvariant;

template<class T, class Allocator>
template<class T>
class recursive_wrapper;

template<class T, class Allocator>
class recursive_wrapper_alloca;


namespace detail {

Expand Down
Loading
Loading