Skip to content

Commit

Permalink
Fixed GCC and clang
Browse files Browse the repository at this point in the history
  • Loading branch information
gracicot committed Apr 26, 2024
1 parent 7ae1225 commit 74792d4
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 24 deletions.
19 changes: 12 additions & 7 deletions include/kangaru/detail/cache.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,12 +142,12 @@ namespace kangaru {

static_assert(cache_map<with_cache<noop_source>>);

template<source Source>
template<source Source, cache_map InnerCache = std::unordered_map<std::size_t, void*>>
struct with_cache_reference_wrapper {
using source_type = source_reference_wrapper_for_t<decltype(std::declval<Source>().source)>;
using cache_type = Source;
using source_type = source_reference_wrapper_for_t<Source>;
using cache_type = with_cache<Source>;

explicit constexpr with_cache_reference_wrapper(with_cache<Source>& source) noexcept :
explicit constexpr with_cache_reference_wrapper(with_cache<Source, InnerCache>& source) noexcept :
source{ref(source.source)}, cache{std::addressof(source)} {}

using key_type = typename cache_type::key_type;
Expand Down Expand Up @@ -222,6 +222,11 @@ namespace kangaru {
swap(cache, other.cache);
}

[[nodiscard]]
constexpr auto unwrap() -> with_cache<Source, InnerCache>& {
return *cache;
}

private:
template<object T, forwarded<with_cache_reference_wrapper> Self>
requires source_of<detail::utility::forward_like_t<Self, source_type>, T>
Expand All @@ -232,9 +237,9 @@ namespace kangaru {
cache_type* cache = {};
};

template<source Source>
struct source_reference_wrapper_for<with_cache<Source>> {
using type = with_cache_reference_wrapper<Source>;
template<source Source, cache_map Cache>
struct source_reference_wrapper_for<with_cache<Source, Cache>> {
using type = with_cache_reference_wrapper<Source, Cache>;
};

static_assert(cache_map<with_cache_reference_wrapper<with_cache<noop_source>>>);
Expand Down
17 changes: 9 additions & 8 deletions include/kangaru/detail/heap_storage.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,12 +168,13 @@ namespace kangaru {
};

static_assert(heap_storage<with_heap_storage<noop_source>>);

Check failure on line 170 in include/kangaru/detail/heap_storage.hpp

View workflow job for this annotation

GitHub Actions / AppleClang XCode 13 MacOS

too few template arguments for class template 'with_heap_storage'

Check failure on line 170 in include/kangaru/detail/heap_storage.hpp

View workflow job for this annotation

GitHub Actions / AppleClang XCode 14 MacOS

too few template arguments for class template 'with_heap_storage'
static_assert(heap_storage<with_heap_storage<noop_source, with_heap_storage<noop_source>>>);

Check failure on line 171 in include/kangaru/detail/heap_storage.hpp

View workflow job for this annotation

GitHub Actions / AppleClang XCode 13 MacOS

too few template arguments for class template 'with_heap_storage'

Check failure on line 171 in include/kangaru/detail/heap_storage.hpp

View workflow job for this annotation

GitHub Actions / AppleClang XCode 14 MacOS

too few template arguments for class template 'with_heap_storage'

template<source Source>
template<source Source, heap_storage InnerStorage = default_heap_storage>

Check failure on line 173 in include/kangaru/detail/heap_storage.hpp

View workflow job for this annotation

GitHub Actions / AppleClang XCode 13 MacOS

unknown type name 'default_heap_storage'

Check failure on line 173 in include/kangaru/detail/heap_storage.hpp

View workflow job for this annotation

GitHub Actions / AppleClang XCode 14 MacOS

unknown type name 'default_heap_storage'
struct with_heap_storage_reference_wrapper {
using source_type = source_reference_wrapper_for_t<decltype(std::declval<Source>().source)>;
using source_type = source_reference_wrapper_for_t<Source>;

explicit constexpr with_heap_storage_reference_wrapper(with_heap_storage<Source>& source) noexcept :
explicit constexpr with_heap_storage_reference_wrapper(with_heap_storage<Source, InnerStorage>& source) noexcept :
source{ref(source.source)}, storage{std::addressof(source)} {}

template<std::copy_constructible F>
Expand All @@ -189,17 +190,17 @@ namespace kangaru {
source_type source;

private:
template<object T> requires source_of<with_heap_storage<Source>, T*>
template<object T> requires source_of<with_heap_storage<Source, InnerStorage>, T*>
friend constexpr auto provide(provide_tag<T*> tag, forwarded<with_heap_storage_reference_wrapper> auto&& source) -> T* {

Check failure on line 194 in include/kangaru/detail/heap_storage.hpp

View workflow job for this annotation

GitHub Actions / Clang 10 Linux

redefinition of 'provide' as different kind of symbol

Check failure on line 194 in include/kangaru/detail/heap_storage.hpp

View workflow job for this annotation

GitHub Actions / Clang 10 Linux

redefinition of 'provide' as different kind of symbol
return provide(tag, *source.storage);
}

with_heap_storage<Source>* storage;
with_heap_storage<Source, InnerStorage>* storage;
};

template<source Source>
struct source_reference_wrapper_for<with_heap_storage<Source>> {
using type = with_heap_storage_reference_wrapper<Source>;
template<source Source, heap_storage Storage>
struct source_reference_wrapper_for<with_heap_storage<Source, Storage>> {
using type = with_heap_storage_reference_wrapper<Source, Storage>;
};

static_assert(heap_storage<with_heap_storage_reference_wrapper<with_heap_storage<noop_source>>>);

Check failure on line 206 in include/kangaru/detail/heap_storage.hpp

View workflow job for this annotation

GitHub Actions / AppleClang XCode 13 MacOS

too few template arguments for class template 'with_heap_storage'

Check failure on line 206 in include/kangaru/detail/heap_storage.hpp

View workflow job for this annotation

GitHub Actions / AppleClang XCode 14 MacOS

too few template arguments for class template 'with_heap_storage'
Expand Down
77 changes: 77 additions & 0 deletions include/kangaru/detail/recursive_source.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,83 @@ namespace kangaru {
private:
Source source;
};

// deep
template<wrapping_source>
struct rebind_wrapper {};

template<template<typename> typename Branch, source Source>
struct rebind_wrapper<Branch<Source>> {
template<source NewSource>
using ttype = Branch<NewSource>;
};

template<template<typename, typename> typename Branch, source Source, typename State>
struct rebind_wrapper<Branch<Source, State>> {
template<source NewSource, typename NewState = State>
using ttype = Branch<NewSource, NewState>;
};

template<typename Source>
concept rebindable_wrapping_source =
wrapping_source<Source>
and requires(Source source) {
typename std::type_identity<typename rebind_wrapper<Source>::template ttype<std::decay_t<decltype(source.source)>>>::type;
requires std::constructible_from<
typename rebind_wrapper<Source>::template ttype<std::decay_t<decltype(source.source)>>,
std::decay_t<decltype(source.source)>
>;
};

template<typename Source>
concept stateful_rebindable_wrapping_source =
rebindable_wrapping_source<Source>
and requires(Source source) {
typename std::type_identity<typename rebind_wrapper<Source>::template ttype<std::decay_t<decltype(source.source)>, decltype(ref(source))>>::type;
requires std::constructible_from<
typename rebind_wrapper<Source>::template ttype<std::decay_t<decltype(source.source)>, decltype(ref(source))>,
std::decay_t<decltype(source.source)>,
decltype(ref(source))
>;
};

template<source Source>
struct with_tree_recursion {
Source source;

auto test() {
return rebind_tree(source);
}

private:
template<kangaru::source Leaf>
constexpr auto rebind_tree(Leaf& source) noexcept -> auto {
return ref(source);
}

template<rebindable_wrapping_source Wrapper>
constexpr auto rebind_tree(Wrapper& source) -> auto {
return typename rebind_wrapper<Wrapper>::ttype{rebind_tree(source.source)};
}

template<stateful_rebindable_wrapping_source Wrapper>
constexpr auto rebind_tree(Wrapper& source) -> auto {
return typename rebind_wrapper<Wrapper>::template ttype<decltype(rebind_tree(source.source)), decltype(ref(source))>{
rebind_tree(source.source),
ref(source),
};
}

template<typename T> requires source_of<Source, T>
friend constexpr auto provide(provide_tag<T> tag, forwarded<with_tree_recursion> auto&& source) {
return provide(tag, KANGARU5_FWD(source).source);
}

template<typename T> requires (not source_of<Source, T>)
friend constexpr auto provide(provide_tag<T> tag, with_tree_recursion& source) {
return provide(tag, source.rebind_tree(source.source));
}
};
}

#include "undef.hpp"
Expand Down
6 changes: 4 additions & 2 deletions include/kangaru/detail/source.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace kangaru {
inline constexpr auto provide_tag_v = provide_tag<T>{};

template<typename T>
concept source = object<T> and std::move_constructible<T>;
concept source = object<T> and std::move_constructible<T> and std::is_class_v<T>;

template<typename T>
concept source_ref = std::is_reference_v<T> and source<std::remove_cvref_t<T>>;
Expand Down Expand Up @@ -74,7 +74,9 @@ namespace kangaru {
or detail::source::member_source_of<Source, T>;

template<typename T>
concept wrapping_source = source<T> and source<std::decay_t<decltype(std::declval<T>().source)>>;
concept wrapping_source =
source<T>
and source<std::decay_t<decltype(std::declval<T>().source)>>;

struct noop_source {};
} // namespace kangaru
Expand Down
20 changes: 20 additions & 0 deletions include/kangaru/detail/source_types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,26 @@ namespace kangaru {
std::tuple<Sources...> sources;
};

template<source... Sources>
struct pick_first_source {
explicit constexpr pick_first_source(std::tuple<Sources...> sources) noexcept : sources{std::move(sources)} {}

template<typename T>
friend constexpr auto provide(provide_tag<T>, forwarded<pick_first_source> auto&& source) -> T
requires ((source_of<detail::utility::forward_like_t<decltype(source), Sources>, T> or ...)) {
constexpr auto index = index_of<T, decltype(source)>(std::index_sequence_for<Sources...>{});
return provide(provide_tag_v<T>, std::get<index>(KANGARU5_FWD(source).sources));
}

private:
template<typename T, typename Self, std::size_t... S>
constexpr static auto index_of(std::index_sequence<S...>) {
return 0;
}

std::tuple<Sources...> sources;
};

template<object... Ts>
struct tuple_source {
explicit constexpr tuple_source(std::tuple<Ts...> objects) noexcept : objects{std::move(objects)} {}
Expand Down
28 changes: 21 additions & 7 deletions tests/src/5-runtime-source.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include "kangaru/detail/recursive_source.hpp"
#include <catch2/catch_test_macros.hpp>
#include <kangaru/kangaru.hpp>

Expand All @@ -20,14 +21,16 @@ struct Derived final : Base {
friend auto tag(kangaru::tag_for<Derived>) -> kangaru::overrides<Base>;
};

struct increment_source {
int n = 0;

constexpr auto provide() -> int {
return n++;
}
} source{};

TEST_CASE("Runtime source will cache sources results", "[deducer]") {
struct increment_source {
int n = 0;

constexpr auto provide() -> int {
return n++;
}
} source{};


SECTION("Will cache the result of sources") {
auto runtime_source = kangaru::with_cache{kangaru::with_heap_storage{kangaru::ref(source)}};

Check failure on line 36 in tests/src/5-runtime-source.cpp

View workflow job for this annotation

GitHub Actions / MSVC Windows

cannot deduce template arguments for 'kangaru::with_cache'

Check failure on line 36 in tests/src/5-runtime-source.cpp

View workflow job for this annotation

GitHub Actions / MSVC Windows

'kangaru::with_cache': the associated constraints are not satisfied

Check failure on line 36 in tests/src/5-runtime-source.cpp

View workflow job for this annotation

GitHub Actions / MSVC Windows

'kangaru::with_cache<Source,Cache> kangaru::with_cache(kangaru::with_cache<Source,Cache>)': could not deduce template argument for 'kangaru::with_cache<Source,Cache>' from 'kangaru::with_heap_storage<kangaru::source_reference_wrapper<Source>,kangaru::default_heap_storage>'
Expand Down Expand Up @@ -60,4 +63,15 @@ TEST_CASE("Runtime source will cache sources results", "[deducer]") {
CHECK(kangaru::provide(kangaru::provide_tag_v<Derived*>, runtime_source)->get() == 3);
CHECK(kangaru::provide(kangaru::provide_tag_v<Base*>, runtime_source)->get() == 0);
}

{
auto source = kangaru::with_heap_storage<increment_source>{increment_source{}};

static_assert(kangaru::stateful_rebindable_wrapping_source<kangaru::with_heap_storage<increment_source>>);
static_assert(kangaru::stateful_rebindable_wrapping_source<kangaru::with_cache<kangaru::with_heap_storage<increment_source>>>);
}

auto basic_recursion_test = kangaru::with_tree_recursion{kangaru::with_cache{kangaru::with_heap_storage{increment_source{}}}};

Check failure on line 74 in tests/src/5-runtime-source.cpp

View workflow job for this annotation

GitHub Actions / MSVC Windows

cannot deduce template arguments for 'kangaru::with_cache'

Check failure on line 74 in tests/src/5-runtime-source.cpp

View workflow job for this annotation

GitHub Actions / MSVC Windows

'kangaru::with_cache': the associated constraints are not satisfied

Check failure on line 74 in tests/src/5-runtime-source.cpp

View workflow job for this annotation

GitHub Actions / MSVC Windows

'kangaru::with_cache<Source,Cache> kangaru::with_cache(kangaru::with_cache<Source,Cache>)': could not deduce template argument for 'kangaru::with_cache<Source,Cache>' from 'kangaru::with_heap_storage<increment_source,kangaru::default_heap_storage>'

CHECK(kangaru::provide(kangaru::provide_tag_v<int*>, basic_recursion_test));
}

0 comments on commit 74792d4

Please sign in to comment.