Skip to content

Commit

Permalink
tests for aa::materialize (#49)
Browse files Browse the repository at this point in the history
* any cast overloads for stateful ref/cref
* tests for aa::materialize
  • Loading branch information
kelbon authored May 8, 2023
1 parent ad8c1ea commit f924056
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 18 deletions.
42 changes: 26 additions & 16 deletions include/anyany/anyany.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1039,20 +1039,20 @@ struct basic_any : construct_interface<basic_any<Alloc, SooS, Methods...>, Metho

static_assert(noexport::is_byte_like_v<typename alloc_traits::value_type>);
static_assert(std::is_nothrow_copy_constructible_v<Alloc>, "C++ Standard requires it");

using base_any_type = basic_any;
using methods_list = ::aa::type_list<Methods...>;

private:
template <typename...>
struct remove_utility_methods {};
template <typename... Methods1>
struct remove_utility_methods<destroy, Methods1...> {
struct remove_utility_methods {
// only way to create basic_any without first 'destroy' method - aa::materialize
using ptr = poly_ptr<Methods1...>;
using const_ptr = const_poly_ptr<Methods1...>;
using ref = poly_ref<Methods1...>;
using const_ref = const_poly_ref<Methods1...>;
};
template <typename... Methods1>
struct remove_utility_methods<destroy, Methods1...> : remove_utility_methods<Methods1...> {};

using purified = remove_utility_methods<Methods...>;

Expand Down Expand Up @@ -1303,11 +1303,11 @@ struct basic_any : construct_interface<basic_any<Alloc, SooS, Methods...>, Metho

// ######################## materialize(create any_with from polymorphic reference)

template <typename Alloc = default_allocator, size_t SooS = default_any_soos, typename... Methods,
std::enable_if_t<(noexport::contains_v<copy_with<Alloc, SooS>, Methods...> &&
noexport::contains_v<destroy, Methods...>),
int> = 0>
basic_any<Alloc, SooS, Methods...> materialize(const_poly_ref<Methods...> ref, Alloc alloc = Alloc{}) {
template <typename Alloc = default_allocator, size_t SooS = default_any_soos, typename... Methods>
auto materialize(const_poly_ref<Methods...> ref, Alloc alloc = Alloc{})
-> std::enable_if_t<(noexport::contains_v<copy_with<Alloc, SooS>, Methods...> &&
noexport::contains_v<destroy, Methods...>),
basic_any<Alloc, SooS, Methods...>> {
basic_any<Alloc, SooS, Methods...> result(aa::allocator_arg, std::move(alloc));
mate::get_value_ptr(result) = invoke<copy_with<Alloc, SooS>>(ref).copy_fn(
mate::get_value_ptr(ref), mate::get_value_ptr(result), mate::get_alloc(result));
Expand All @@ -1316,13 +1316,13 @@ basic_any<Alloc, SooS, Methods...> materialize(const_poly_ref<Methods...> ref, A
}
#define AA_DECLARE_MATERIALIZE(TEMPLATE, TRANSFORM) \
template <typename Alloc = default_allocator, size_t SooS = default_any_soos, typename... Methods> \
AA_ALWAYS_INLINE auto materialize(TEMPLATE<Methods...> value, Alloc alloc = Alloc{}) \
->decltype(materialize<Alloc, SooS>(TRANSFORM, std::move(alloc))) { \
return materialize<Alloc, SooS>(TRANSFORM, std::move(alloc)); \
AA_ALWAYS_INLINE auto materialize(const TEMPLATE<Methods...>& value, Alloc alloc = Alloc{}) \
->decltype(materialize<Alloc, SooS, Methods...>(TRANSFORM, std::move(alloc))) { \
return materialize<Alloc, SooS, Methods...>(TRANSFORM, std::move(alloc)); \
}
AA_DECLARE_MATERIALIZE(poly_ref, const_poly_ref(value))
AA_DECLARE_MATERIALIZE(stateful::ref, value.get_view())
AA_DECLARE_MATERIALIZE(stateful::cref, value.get_view())
AA_DECLARE_MATERIALIZE(stateful::ref, const_poly_ref(value.get_view()))
AA_DECLARE_MATERIALIZE(stateful::cref, const_poly_ref(value.get_view()))
#undef AA_DECLARE_MATERIALIZE

// ######################## ACTION any_cast ########################
Expand Down Expand Up @@ -1439,13 +1439,23 @@ struct any_cast_fn<T, anyany_poly_traits> {
throw aa::bad_cast{};
return *ptr;
}
template<typename... Methods>
decltype(auto) operator()(const stateful::ref<Methods...>& r) const {
return (*this)(r.get_view());
}
template <typename... Methods>
decltype(auto) operator()(const stateful::cref<Methods...>& r) const {
return (*this)(r.get_view());
}
};

template <typename T, AA_CONCEPT(poly_traits) Traits = anyany_poly_traits>
constexpr inline any_cast_fn<T, Traits> any_cast = {};

template <typename Alloc, size_t SooS, anyany_method_concept... Methods>
using basic_any_with = basic_any<Alloc, SooS, destroy, Methods...>;
using basic_any_with =
std::conditional_t<noexport::contains_v<destroy, Methods...>, basic_any<Alloc, SooS, Methods...>,
basic_any<Alloc, SooS, destroy, Methods...>>;

template <anyany_method_concept... Methods>
using any_with = basic_any_with<default_allocator, default_any_soos, Methods...>;
Expand All @@ -1459,7 +1469,7 @@ using cref = const_poly_ref<Methods...>;
// just an alias for set of interface requirements, may be used later in 'insert_flatten_into'
template<typename...MethodOrInterfaceAlias>
using interface_alias = type_list<MethodOrInterfaceAlias...>;
// Methods may be aa::compound_method<...> or just anyany Methods
// Methods may be aa::interface_alias<...> or just anyany Methods
// using input_iterator_interface = aa::interface_alias<next, is_done, aa::move>;
// example: insert_flatten_into<aa::any_with, input_iterator_interface, foo, bar>
// same as aa::any_with<next, is_done, aa::move, foo, bar>;
Expand Down
4 changes: 4 additions & 0 deletions include/anyany/noexport/file_begin.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,8 @@ Try set it manually (see anyany/CMakeLists.txt for example)
public: \
static constexpr inline bool value = check_fn_impl<std::decay_t<U>>(0); \
}
#ifdef __clang__
#define ANYANY_LIFETIMEBOUND [[clang::lifetimebound]]
#else
#define ANYANY_LIFETIMEBOUND
#endif
36 changes: 34 additions & 2 deletions tests/test_anyany.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -809,7 +809,39 @@ TEST(subtable_ptr) {
error_if(std::abs(p_end2 - p_end1) != sizeof(typename m2<2>::value_type));
return error_count;
}

template<typename Alloc, size_t SooS>
struct inserter {
template <typename... Ts>
using type = aa::basic_any<Alloc, SooS, Ts...>;
};
TEST(materialize) {
auto test = [&](auto type_list_v, auto alloc, auto soos) {
std::string s = "hello world";
aa::insert_flatten_into<inserter<decltype(alloc), soos.value>::template type, decltype(type_list_v)> obj =
s;
aa::insert_flatten_into<aa::poly_ref, decltype(type_list_v)> ref0 = s;
error_if(aa::any_cast<std::string>(ref0) != s);
aa::const_poly_ref ref1 = ref0;
error_if(aa::any_cast<std::string>(ref1) != s);
aa::stateful::ref ref2 = ref0;
error_if(aa::any_cast<std::string>(ref2) != s);
aa::stateful::cref ref3 = ref0;
error_if(aa::any_cast<std::string>(ref3) != s);
std::vector v{
aa::materialize<decltype(alloc), soos.value>(ref0),
aa::materialize<decltype(alloc), soos.value>(ref1),
aa::materialize<decltype(alloc), soos.value>(ref2),
aa::materialize<decltype(alloc), soos.value>(ref3),
};
error_if(std::any_of(begin(v), end(v), [&](auto& x) { return x != obj; }));
};
test(aa::interface_alias<aa::destroy, aa::copy, aa::equal_to>{}, aa::default_allocator{},
std::integral_constant<size_t, aa::default_any_soos>{});
test(
aa::interface_alias<aa::equal_to, aa::destroy, aa::destroy, aa::copy_with<aa::unreachable_allocator>>{},
aa::unreachable_allocator{}, std::integral_constant<size_t, aa::default_any_soos>{});
return error_count;
}
int main() {
std::cout << "C++ standard: " << __cplusplus << std::endl;
// compile time checks
Expand Down Expand Up @@ -1086,5 +1118,5 @@ int main() {
srand(time(0));
return TESTconstructors() + TESTany_cast() + TESTany_cast2() + TESTinvoke() + TESTcompare() +
TESTtype_descriptor_and_plugins_interaction() + TESTspecial_member_functions() + TESTptr_behavior() +
TESTtransmutate_ctors() + TESTstateful() + TESTsubtable_ptr();
TESTtransmutate_ctors() + TESTstateful() + TESTsubtable_ptr() + TESTmaterialize();
}

0 comments on commit f924056

Please sign in to comment.