Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow always allocated #66

Merged
merged 5 commits into from
Feb 1, 2024
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
19 changes: 14 additions & 5 deletions include/anyany/anyany.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1099,15 +1099,24 @@ struct unreachable_allocator {
// strong exception guarantee for all constructors and assignments,
// emplace<T> - *this is empty if exception thrown
// for alloc not all fancy pointers supported and construct / destroy not throught alloc
// if SooS == 0, value is always allocated, is_stable_pointers() == true
template <typename Alloc, size_t SooS, typename... Methods>
struct basic_any : construct_interface<basic_any<Alloc, SooS, Methods...>, Methods...> {
using aa_polymorphic_tag = int;

private:
static AA_CONSTEVAL_CPP20 size_t soo_buffer_size() noexcept {
// needs atleast sizeof(std::size_t) in buffer(SooS)
// to store allocated size for passing it into deallocate(ptr, n)
static_assert(SooS == 0 || SooS >= sizeof(size_t),
"basic_any requires SooS to be >= sizeof(size_t) or 0");
return SooS == 0 ? sizeof(size_t) : SooS;
}

const vtable<Methods...>* vtable_ptr = nullptr;
void* value_ptr = data;
union {
alignas(std::max_align_t) std::byte data[SooS];
alignas(std::max_align_t) std::byte data[soo_buffer_size()];
size_t size_allocated; // stored when value allocated
};
#if __clang__
Expand Down Expand Up @@ -1375,10 +1384,13 @@ struct basic_any : construct_interface<basic_any<Alloc, SooS, Methods...>, Metho

// observe

enum : bool { is_always_stable_pointers = SooS == 0 };

// returns true if poly_ptr/ref to this basic_any will not be invalidated after move
constexpr bool is_stable_pointers() const noexcept {
return memory_allocated();
}

constexpr bool has_value() const noexcept {
return vtable_ptr != nullptr;
}
Expand All @@ -1388,7 +1400,7 @@ struct basic_any : construct_interface<basic_any<Alloc, SooS, Methods...>, Metho
constexpr size_t sizeof_now() const noexcept {
if (!has_value())
return 0;
return memory_allocated() ? allocated_size() : SooS;
return memory_allocated() ? allocated_size() : SooS;//HMM
}

private:
Expand Down Expand Up @@ -1431,9 +1443,6 @@ struct basic_any : construct_interface<basic_any<Alloc, SooS, Methods...>, Metho
}
constexpr size_t allocated_size() const noexcept {
assert(has_value() && memory_allocated());
// needs atleast sizeof(std::size_t) in buffer(SooS)
// to store allocated size for passing it into deallocate(ptr, n)
static_assert(SooS >= sizeof(std::size_t));
// when allocates stores in size in unused buffer
return size_allocated;
}
Expand Down
23 changes: 22 additions & 1 deletion tests/test_anyany.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1248,6 +1248,27 @@ struct forward_declared_method {
void fwd_declare(aa::const_poly_ref<forward_declared_method> ref) {
aa::invoke<forward_declared_method>(ref);
}

TEST(always_allocated_any) {
using aa_aa = aa::basic_any_with<aa::default_allocator, 0, aa::copy_with<aa::default_allocator, 0>>;
aa_aa x = 'c';
error_if(!x.is_stable_pointers());
error_if(x.sizeof_now() != sizeof(char));
error_if(!x.is_always_stable_pointers);
auto x_copy = x;
error_if(!x_copy.is_stable_pointers());
error_if(x_copy.sizeof_now() != sizeof(char));
error_if(!x_copy.is_always_stable_pointers);
auto y = std::move(x);
error_if(x.is_stable_pointers());
error_if(x.sizeof_now() != 0);
error_if(!x.is_always_stable_pointers);
error_if(!y.is_stable_pointers());
error_if(y.sizeof_now() != sizeof(char));
error_if(!y.is_always_stable_pointers);
return error_count;
}

int main() {
fwd_declare(5);
std::cout << "C++ standard: " << __cplusplus << std::endl;
Expand Down Expand Up @@ -1524,5 +1545,5 @@ int main() {
return TESTconstructors() + TESTany_cast() + TESTany_cast2() + TESTinvoke() + TESTcompare() +
TESTtype_descriptor_and_plugins_interaction() + TESTspecial_member_functions() + TESTptr_behavior() +
TESTtransmutate_ctors() + TESTstateful() + TESTsubtable_ptr() + TESTmaterialize() +
TESTruntime_reflection() + TESTcustom_unique_ptr() + TESTstrange_allocs();
TESTruntime_reflection() + TESTcustom_unique_ptr() + TESTstrange_allocs() + TESTalways_allocated_any();
}
Loading