Skip to content

Commit

Permalink
Extend the Const accessor to support proxy references
Browse files Browse the repository at this point in the history
  • Loading branch information
bernhardmgruber committed Nov 29, 2022
1 parent d87e08e commit 5aa4048
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 0 deletions.
30 changes: 30 additions & 0 deletions include/llama/Accessors.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include "Concepts.hpp"
#include "ProxyRefOpMixin.hpp"
#include "macros.hpp"

#include <atomic>
Expand Down Expand Up @@ -34,11 +35,40 @@ namespace llama::accessor
/// Allows only read access by qualifying the references to memory with const. Only works on l-value references.
struct Const
{
// for l-value references
template<typename T>
LLAMA_FN_HOST_ACC_INLINE auto operator()(T& r) const -> const T&
{
return r;
}

template<typename Ref>
struct Reference : ProxyRefOpMixin<Reference<Ref>, typename Ref::value_type>
{
using value_type = typename Ref::value_type;

Ref ref;

// NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)
operator value_type() const
{
return static_cast<value_type>(ref);
}

template<typename T>
auto operator=(T) -> Reference&
{
static_assert(sizeof(T) == 0, "You cannot write through a Const accessor");
return *this;
}
};

// for proxy references
template<typename ProxyReference, std::enable_if_t<llama::isProxyReference<ProxyReference>, int> = 0>
LLAMA_FN_HOST_ACC_INLINE auto operator()(ProxyReference r) const
{
return Reference<ProxyReference>{{}, std::move(r)};
}
};

/// Qualifies references to memory with __restrict. Only works on l-value references.
Expand Down
19 changes: 19 additions & 0 deletions tests/accessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,25 @@ TEMPLATE_TEST_CASE(
iotaCheckView(view);
}

TEST_CASE("view.withAccessor.shallowCopy.Const")
{
auto view
= llama::allocView(llama::mapping::AoS{llama::ArrayExtents{4, 4}, Vec3I{}}, llama::bloballoc::SharedPtr{});
iotaFillView(view);
auto view2 = llama::withAccessor<llama::accessor::Const>(llama::shallowCopy(view));
iotaCheckView(view2);
}

TEST_CASE("view.withAccessor.shallowCopy.Const.ProxyRef")
{
auto view = llama::allocView(
llama::mapping::Byteswap<llama::ArrayExtents<int, 4, 4>, Vec3I, llama::mapping::BindAoS<>::fn>{{}},
llama::bloballoc::SharedPtr{});
iotaFillView(view);
auto view2 = llama::withAccessor<llama::accessor::Const>(llama::shallowCopy(view));
iotaCheckView(view2);
}

#ifdef __cpp_lib_atomic_ref
TEMPLATE_TEST_CASE(
"view.withAccessor.shallowCopy.Atomic",
Expand Down

0 comments on commit 5aa4048

Please sign in to comment.