Skip to content

Commit

Permalink
added rvalue typedefs
Browse files Browse the repository at this point in the history
also:
- added `source_offset` customization point for mix-ins
  • Loading branch information
marzer committed Aug 29, 2023
1 parent 1d86b36 commit 14ab503
Show file tree
Hide file tree
Showing 15 changed files with 649 additions and 99 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## Unreleased

- Added `rvalue_row_type<>`
- Added `rvalue_iterator_type<>`
- Added `rvalue_span_type<>`
- Added `source_offset` customization point for mix-ins

## v0.7.0

- Fixed rvalue row corruption bug on MSVC ([info](https://developercommunity.visualstudio.com/t/C:-Corrupt-references-when-creating-a/10446877))
Expand Down
6 changes: 3 additions & 3 deletions examples/entities.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ namespace soagen::examples
using iterator = soagen::iterator_type<entities>;

/// @brief Row iterators returned by rvalue-qualified iterator functions.
using rvalue_iterator = soagen::iterator_type<entities&&>;
using rvalue_iterator = soagen::rvalue_iterator_type<entities>;

/// @brief Row iterators returned by const-qualified iterator functions.
using const_iterator = soagen::const_iterator_type<entities>;
Expand All @@ -270,7 +270,7 @@ namespace soagen::examples
using span_type = soagen::span_type<entities>;

/// @brief Rvalue-qualified span type.
using rvalue_span_type = soagen::span_type<entities&&>;
using rvalue_span_type = soagen::rvalue_span_type<entities>;

/// @brief Const-qualified span type.
using const_span_type = soagen::const_span_type<entities>;
Expand All @@ -279,7 +279,7 @@ namespace soagen::examples
using row_type = soagen::row_type<entities>;

/// @brief Rvalue row type used by this class.
using rvalue_row_type = soagen::row_type<entities&&>;
using rvalue_row_type = soagen::rvalue_row_type<entities>;

/// @brief Const row type used by this class.
using const_row_type = soagen::const_row_type<entities>;
Expand Down
12 changes: 6 additions & 6 deletions examples/shapes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ namespace soagen::examples
using iterator = soagen::iterator_type<boxes>;

/// @brief Row iterators returned by rvalue-qualified iterator functions.
using rvalue_iterator = soagen::iterator_type<boxes&&>;
using rvalue_iterator = soagen::rvalue_iterator_type<boxes>;

/// @brief Row iterators returned by const-qualified iterator functions.
using const_iterator = soagen::const_iterator_type<boxes>;
Expand All @@ -353,7 +353,7 @@ namespace soagen::examples
using span_type = soagen::span_type<boxes>;

/// @brief Rvalue-qualified span type.
using rvalue_span_type = soagen::span_type<boxes&&>;
using rvalue_span_type = soagen::rvalue_span_type<boxes>;

/// @brief Const-qualified span type.
using const_span_type = soagen::const_span_type<boxes>;
Expand All @@ -362,7 +362,7 @@ namespace soagen::examples
using row_type = soagen::row_type<boxes>;

/// @brief Rvalue row type used by this class.
using rvalue_row_type = soagen::row_type<boxes&&>;
using rvalue_row_type = soagen::rvalue_row_type<boxes>;

/// @brief Const row type used by this class.
using const_row_type = soagen::const_row_type<boxes>;
Expand Down Expand Up @@ -1518,7 +1518,7 @@ namespace soagen::examples
using iterator = soagen::iterator_type<spheres>;

/// @brief Row iterators returned by rvalue-qualified iterator functions.
using rvalue_iterator = soagen::iterator_type<spheres&&>;
using rvalue_iterator = soagen::rvalue_iterator_type<spheres>;

/// @brief Row iterators returned by const-qualified iterator functions.
using const_iterator = soagen::const_iterator_type<spheres>;
Expand All @@ -1527,7 +1527,7 @@ namespace soagen::examples
using span_type = soagen::span_type<spheres>;

/// @brief Rvalue-qualified span type.
using rvalue_span_type = soagen::span_type<spheres&&>;
using rvalue_span_type = soagen::rvalue_span_type<spheres>;

/// @brief Const-qualified span type.
using const_span_type = soagen::const_span_type<spheres>;
Expand All @@ -1536,7 +1536,7 @@ namespace soagen::examples
using row_type = soagen::row_type<spheres>;

/// @brief Rvalue row type used by this class.
using rvalue_row_type = soagen::row_type<spheres&&>;
using rvalue_row_type = soagen::rvalue_row_type<spheres>;

/// @brief Const row type used by this class.
using const_row_type = soagen::const_row_type<spheres>;
Expand Down
34 changes: 34 additions & 0 deletions src/soagen/hpp/core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -760,6 +760,26 @@ namespace soagen
};
template <typename T>
using add_const_to_first_type_arg = typename add_const_to_first_type_arg_<T>::type;

template <typename>
struct add_rvalue_to_first_type_arg_;
template <template <typename> typename Type, typename T>
struct add_rvalue_to_first_type_arg_<Type<T>>
{
using type = Type<std::add_rvalue_reference_t<std::remove_reference_t<T>>>;
};
template <template <typename, typename...> typename Type, typename T, typename... Args>
struct add_rvalue_to_first_type_arg_<Type<T, Args...>>
{
using type = Type<std::add_rvalue_reference_t<std::remove_reference_t<T>>, Args...>;
};
template <template <typename, size_t...> typename Type, typename T, size_t... Columns>
struct add_rvalue_to_first_type_arg_<Type<T, Columns...>>
{
using type = Type<std::add_rvalue_reference_t<std::remove_reference_t<T>>, Columns...>;
};
template <typename T>
using add_rvalue_to_first_type_arg = typename add_rvalue_to_first_type_arg_<T>::type;
}
/// @endcond

Expand All @@ -768,6 +788,10 @@ namespace soagen
template <typename T>
using span_type = POXY_IMPLEMENTATION_DETAIL(span<remove_lvalue_ref<detail::soa_type_cvref<remove_lvalue_ref<T>>>>);

/// @brief The same as #soagen::span_type but promoting the base SoA type to `&&` (if it was not already).
template <typename T>
using rvalue_span_type = POXY_IMPLEMENTATION_DETAIL(detail::add_rvalue_to_first_type_arg<span_type<T>>);

/// @brief The same as #soagen::span_type but promoting the base SoA type to `const` (if it was not already).
template <typename T>
using const_span_type = POXY_IMPLEMENTATION_DETAIL(detail::add_const_to_first_type_arg<span_type<T>>);
Expand Down Expand Up @@ -800,6 +824,11 @@ namespace soagen
using row_type = POXY_IMPLEMENTATION_DETAIL(
detail::derive_view_type<row, T, std::index_sequence<static_cast<size_t>(Columns)...>>);

/// @brief The same as #soagen::row_type but promoting the base SoA type to `&&` (if it was not already).
template <typename T, auto... Columns>
using rvalue_row_type =
POXY_IMPLEMENTATION_DETAIL(detail::add_rvalue_to_first_type_arg<row_type<T, static_cast<size_t>(Columns)...>>);

/// @brief The same as #soagen::row_type but promoting the base SoA type to `const` (if it was not already).
template <typename T, auto... Columns>
using const_row_type =
Expand All @@ -812,6 +841,11 @@ namespace soagen
using iterator_type = POXY_IMPLEMENTATION_DETAIL(
detail::derive_view_type<iterator, T, std::index_sequence<static_cast<size_t>(Columns)...>>);

/// @brief The same as #soagen::iterator_type but promoting the base SoA type to `&&` (if it was not already).
template <typename T, auto... Columns>
using rvalue_iterator_type = POXY_IMPLEMENTATION_DETAIL(
detail::add_rvalue_to_first_type_arg<iterator_type<T, static_cast<size_t>(Columns)...>>);

/// @brief The same as #soagen::iterator_type but promoting the base SoA type to `const` (if it was not already).
template <typename T, auto... Columns>
using const_iterator_type = POXY_IMPLEMENTATION_DETAIL(
Expand Down
76 changes: 64 additions & 12 deletions src/soagen/hpp/mixins/iterators.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#pragma once

#include "../invoke.hpp"
#include "../source_offset.hpp"
#include "../header_start.hpp"

namespace soagen::mixins
Expand All @@ -16,52 +17,103 @@ namespace soagen::mixins

using difference_type = std::ptrdiff_t;
using iterator = soagen::iterator_type<Derived>;
using rvalue_iterator = soagen::iterator_type<Derived&&>;
using rvalue_iterator = soagen::rvalue_iterator_type<Derived>;
using const_iterator = soagen::const_iterator_type<Derived>;

template <auto... Cols>
SOAGEN_PURE_INLINE_GETTER
constexpr iterator_type<Derived, Cols...> begin() & noexcept
{
return { static_cast<Derived&>(*this), 0 };
if constexpr (std::is_same_v<soa_type<remove_cvref<Derived>>, Derived>)
{
return { static_cast<Derived&>(*this), 0 };
}
else
{
return { static_cast<soa_type<Derived>&>(static_cast<Derived&>(*this)),
static_cast<difference_type>(get_source_offset(static_cast<const Derived&>(*this))) };
}
}

template <auto... Cols>
SOAGEN_PURE_INLINE_GETTER
constexpr iterator_type<Derived, Cols...> end() & noexcept
{
return { static_cast<Derived&>(*this),
static_cast<difference_type>(static_cast<const Derived&>(*this).size()) };
if constexpr (std::is_same_v<soa_type<remove_cvref<Derived>>, Derived>)
{
return { static_cast<Derived&>(*this),
static_cast<difference_type>(static_cast<const Derived&>(*this).size()) };
}
else
{
return { static_cast<soa_type<Derived>&>(static_cast<Derived&>(*this)),
static_cast<difference_type>(get_source_offset(static_cast<const Derived&>(*this)))
+ static_cast<difference_type>(static_cast<const Derived&>(*this).size()) };
}
}

template <auto... Cols>
SOAGEN_PURE_INLINE_GETTER
constexpr iterator_type<Derived&&, Cols...> begin() && noexcept
constexpr rvalue_iterator_type<Derived, Cols...> begin() && noexcept
{
return { static_cast<Derived&&>(*this), 0 };
if constexpr (std::is_same_v<soa_type<remove_cvref<Derived>>, Derived>)
{
return { static_cast<Derived&&>(*this), 0 };
}
else
{
return { static_cast<soa_type<Derived>&&>(static_cast<Derived&&>(*this)),
static_cast<difference_type>(get_source_offset(static_cast<const Derived&>(*this))) };
}
}

template <auto... Cols>
SOAGEN_PURE_INLINE_GETTER
constexpr iterator_type<Derived&&, Cols...> end() && noexcept
constexpr rvalue_iterator_type<Derived, Cols...> end() && noexcept
{
return { static_cast<Derived&&>(*this),
static_cast<difference_type>(static_cast<const Derived&>(*this).size()) };
if constexpr (std::is_same_v<soa_type<remove_cvref<Derived>>, Derived>)
{
return { static_cast<Derived&&>(*this),
static_cast<difference_type>(static_cast<const Derived&>(*this).size()) };
}
else
{
return { static_cast<soa_type<Derived>&&>(static_cast<Derived&&>(*this)),
static_cast<difference_type>(get_source_offset(static_cast<const Derived&>(*this)))
+ static_cast<difference_type>(static_cast<const Derived&>(*this).size()) };
}
}

template <auto... Cols>
SOAGEN_PURE_INLINE_GETTER
constexpr const_iterator_type<Derived, Cols...> begin() const& noexcept
{
return { static_cast<const Derived&>(*this), 0 };
if constexpr (std::is_same_v<soa_type<remove_cvref<Derived>>, Derived>)
{
return { static_cast<const Derived&>(*this), 0 };
}
else
{
return { static_cast<const soa_type<Derived>&>(static_cast<const Derived&>(*this)),
static_cast<difference_type>(get_source_offset(static_cast<const Derived&>(*this))) };
}
}

template <auto... Cols>
SOAGEN_PURE_INLINE_GETTER
constexpr const_iterator_type<Derived, Cols...> end() const& noexcept
{
return { static_cast<const Derived&>(*this),
static_cast<difference_type>(static_cast<const Derived&>(*this).size()) };
if constexpr (std::is_same_v<soa_type<remove_cvref<Derived>>, Derived>)
{
return { static_cast<const Derived&>(*this),
static_cast<difference_type>(static_cast<const Derived&>(*this).size()) };
}
else
{
return { static_cast<const soa_type<Derived>&>(static_cast<Derived&&>(*this)),
static_cast<difference_type>(get_source_offset(static_cast<const Derived&>(*this)))
+ static_cast<difference_type>(static_cast<const Derived&>(*this).size()) };
}
}

template <auto... Cols>
Expand Down
12 changes: 6 additions & 6 deletions src/soagen/hpp/mixins/rows.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ namespace soagen::mixins

using size_type = std::size_t;
using row_type = soagen::row_type<Derived>;
using rvalue_row_type = soagen::row_type<Derived&&>;
using rvalue_row_type = soagen::rvalue_row_type<Derived>;
using const_row_type = soagen::const_row_type<Derived>;

template <auto... Cols>
Expand All @@ -43,11 +43,11 @@ namespace soagen::mixins
template <auto... Cols>
SOAGEN_PURE_GETTER
SOAGEN_CPP20_CONSTEXPR
soagen::row_type<Derived&&, Cols...> row(size_type index) && noexcept
soagen::rvalue_row_type<Derived, Cols...> row(size_type index) && noexcept
{
#if SOAGEN_MSVC
// https://developercommunity.visualstudio.com/t/C:-Corrupt-references-when-creating-a/10446877
return static_cast<soagen::row_type<Derived&&, Cols...>>(
return static_cast<soagen::rvalue_row_type<Derived, Cols...>>(
static_cast<Derived&>(*this).template row<Cols...>(index));
#else

Expand Down Expand Up @@ -117,7 +117,7 @@ namespace soagen::mixins
template <auto... Cols>
SOAGEN_PURE_GETTER
SOAGEN_CPP20_CONSTEXPR
soagen::row_type<Derived&&, Cols...> at(size_type index) &&
soagen::rvalue_row_type<Derived, Cols...> at(size_type index) &&
{
#if SOAGEN_HAS_EXCEPTIONS
if (index >= static_cast<const Derived&>(*this).size())
Expand Down Expand Up @@ -157,15 +157,15 @@ namespace soagen::mixins
template <auto... Cols>
SOAGEN_PURE_INLINE_GETTER
SOAGEN_CPP20_CONSTEXPR
soagen::row_type<Derived&&, Cols...> front() && noexcept
soagen::rvalue_row_type<Derived, Cols...> front() && noexcept
{
return static_cast<rows&&>(*this).template row<static_cast<size_type>(Cols)...>(0u);
}

template <auto... Cols>
SOAGEN_PURE_INLINE_GETTER
SOAGEN_CPP20_CONSTEXPR
soagen::row_type<Derived&&, Cols...> back() && noexcept
soagen::rvalue_row_type<Derived, Cols...> back() && noexcept
{
return static_cast<rows&&>(*this).template row<static_cast<size_type>(Cols)...>(
static_cast<const Derived&>(*this).size() - 1u);
Expand Down
Loading

0 comments on commit 14ab503

Please sign in to comment.