Skip to content

Commit

Permalink
Add trait isProxyReference
Browse files Browse the repository at this point in the history
  • Loading branch information
bernhardmgruber committed Jul 1, 2022
1 parent 173563d commit 9dfe9b8
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 4 deletions.
32 changes: 28 additions & 4 deletions include/llama/Concepts.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
#if __has_include(<concepts>)
# include <concepts>
#endif
#ifdef __cpp_lib_concepts
namespace llama
{
#ifdef __cpp_lib_concepts
// clang-format off
template <typename M>
concept Mapping = requires(M m) {
Expand Down Expand Up @@ -50,7 +50,7 @@ namespace llama
concept ProxyReference = requires(R r) {
typename R::value_type;
{ static_cast<typename R::value_type>(r) } -> std::same_as<typename R::value_type>;
{ r = typename R::value_type{} } -> std::same_as<R&>;
{ r = std::declval<typename R::value_type>() } -> std::same_as<R&>;
};

template <typename R>
Expand Down Expand Up @@ -100,7 +100,31 @@ namespace llama
concept BlobAllocator = requires(BA ba, std::integral_constant<std::size_t, 16> alignment, std::size_t size) {
{ ba(alignment, size) } -> Blob;
};
// clang-format on
} // namespace llama
// clang-format on
#endif

namespace internal
{
template<typename R, typename = void>
struct IsProxyReferenceImpl : std::false_type
{
};

template<typename R>
struct IsProxyReferenceImpl<
R,
std::void_t<
typename R::value_type,
decltype(static_cast<typename R::value_type>(std::declval<R&>())),
decltype(std::declval<R&>() = std::declval<typename R::value_type>())>> : std::true_type
{
};
} // namespace internal

template<typename R>
#ifdef __cpp_lib_concepts
inline constexpr bool isProxyReference = ProxyReference<R>;
#else
inline constexpr bool isProxyReference = internal::IsProxyReferenceImpl<R>::value;
#endif
} // namespace llama
24 changes: 24 additions & 0 deletions tests/core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -508,3 +508,27 @@ TEST_CASE("divCeil")
STATIC_REQUIRE(llama::divCeil(17, 16) == 2);
STATIC_REQUIRE(llama::divCeil(300, 16) == 19);
}

TEST_CASE("isProxyReference")
{
STATIC_REQUIRE(!llama::internal::IsProxyReferenceImpl<int&>::value);
STATIC_REQUIRE(!llama::isProxyReference<int&>);
STATIC_REQUIRE(!llama::internal::IsProxyReferenceImpl<std::string>::value);
STATIC_REQUIRE(!llama::isProxyReference<std::string>);
STATIC_REQUIRE(!llama::internal::IsProxyReferenceImpl<std::vector<int>>::value);
STATIC_REQUIRE(!llama::isProxyReference<std::vector<int>>);
STATIC_REQUIRE(!llama::internal::IsProxyReferenceImpl<std::vector<bool>::reference>::value);
STATIC_REQUIRE(!llama::isProxyReference<std::vector<bool>::reference>); // misses a value_type alias

using One = llama::One<Vec3I>;
STATIC_REQUIRE(!llama::internal::IsProxyReferenceImpl<One>::value);
STATIC_REQUIRE(!llama::isProxyReference<One>);
STATIC_REQUIRE(!llama::internal::IsProxyReferenceImpl<decltype(One{}())>::value);
STATIC_REQUIRE(!llama::isProxyReference<decltype(One{}())>);

auto mapping = llama::mapping::BitPackedIntSoA<llama::ArrayExtents<int, 4>, Vec3I>{{}, 17};
auto v = llama::allocView(mapping);
[[maybe_unused]] auto ref = v(1)(tag::X{});
STATIC_REQUIRE(llama::internal::IsProxyReferenceImpl<decltype(ref)>::value);
STATIC_REQUIRE(llama::isProxyReference<decltype(ref)>);
}

0 comments on commit 9dfe9b8

Please sign in to comment.