Skip to content

Commit

Permalink
Unduplicate getters using this auto&& self and std::forward_like.
Browse files Browse the repository at this point in the history
  • Loading branch information
Jhuighuy committed Dec 20, 2024
1 parent 055face commit c6d9edd
Show file tree
Hide file tree
Showing 8 changed files with 52 additions and 164 deletions.
2 changes: 2 additions & 0 deletions cmake/clang.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ set(
-march=native
# Position independent code.
-fPIC
# Bug in LLVM.
-fno-builtin-std-forward_like
)

# When compiling with GCC, force LLVM tools to use libstdc++.
Expand Down
32 changes: 8 additions & 24 deletions source/tit/core/_mat/mat.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <array>
#include <format>
#include <initializer_list>
#include <utility>

#include "tit/core/basic_types.hpp"
#include "tit/core/checks.hpp"
Expand Down Expand Up @@ -48,40 +49,23 @@ class Mat final {
}

/// Matrix rows array.
/// @{
constexpr auto rows() noexcept -> std::array<Row, Dim>& {
return rows_;
}
constexpr auto rows() const noexcept -> const std::array<Row, Dim>& {
return rows_;
constexpr auto rows(this auto&& self) noexcept -> auto&& {
return std::forward_like<decltype(self)>(self.rows_);
}
/// @}

/// Matrix row at index.
/// @{
constexpr auto operator[](size_t i) noexcept -> Row& {
TIT_ASSERT(i < Dim, "Row index is out of range!");
return rows_[i];
}
constexpr auto operator[](size_t i) const noexcept -> const Row& {
constexpr auto operator[](this auto&& self, size_t i) noexcept -> auto&& {
TIT_ASSERT(i < Dim, "Row index is out of range!");
return rows_[i];
return std::forward_like<decltype(self)>(self.rows_[i]);
}
/// @}

/// Matrix element at index.
/// @{
constexpr auto operator[](size_t i, size_t j) noexcept -> Num& {
TIT_ASSERT(i < Dim, "Row index is out of range!");
TIT_ASSERT(j < Dim, "Column index is out of range!");
return rows_[i][j];
}
constexpr auto operator[](size_t i, size_t j) const noexcept -> const Num& {
constexpr auto operator[](this auto&& self, size_t i, size_t j) noexcept
-> auto&& {
TIT_ASSERT(i < Dim, "Row index is out of range!");
TIT_ASSERT(j < Dim, "Column index is out of range!");
return rows_[i][j];
return std::forward_like<decltype(self)>(self.rows_[i][j]);
}
/// @}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down
50 changes: 11 additions & 39 deletions source/tit/core/_vec/vec.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,26 +51,15 @@ class Vec final {
}

/// Vector elements array.
/// @{
constexpr auto elems() noexcept -> std::array<Num, Dim>& {
return col_;
constexpr auto elems(this auto&& self) noexcept -> auto&& {
return std::forward_like<decltype(self)>(self.col_);
}
constexpr auto elems() const noexcept -> const std::array<Num, Dim>& {
return col_;
}
/// @}

/// Vector element at index.
/// @{
constexpr auto operator[](size_t i) noexcept -> Num& {
TIT_ASSERT(i < Dim, "Row index is out of range!");
return col_[i];
}
constexpr auto operator[](size_t i) const noexcept -> const Num& {
constexpr auto operator[](this auto&& self, size_t i) noexcept -> auto&& {
TIT_ASSERT(i < Dim, "Row index is out of range!");
return col_[i];
return std::forward_like<decltype(self)>(self.col_[i]);
}
/// @}

private:

Expand Down Expand Up @@ -166,38 +155,21 @@ class Vec<Num, Dim> final {
}

/// Vector elements array.
/// @{
constexpr auto elems() noexcept -> std::array<Num, Dim>& {
return col_;
}
constexpr auto elems() const noexcept -> const std::array<Num, Dim>& {
return col_;
constexpr auto elems(this auto&& self) noexcept -> auto&& {
return std::forward_like<decltype(self)>(self.col_);
}
/// @}

/// Vector element at index.
/// @{
constexpr auto operator[](size_t i) noexcept -> Num& {
constexpr auto operator[](this auto&& self, size_t i) noexcept -> auto&& {
TIT_ASSERT(i < Dim, "Row index is out of range!");
return col_[i];
return std::forward_like<decltype(self)>(self.col_[i]);
}
constexpr auto operator[](size_t i) const noexcept -> const Num& {
TIT_ASSERT(i < Dim, "Row index is out of range!");
return col_[i];
}
/// @}

/// Underlying register at index.
/// @{
auto reg(size_t i) noexcept -> Reg& {
TIT_ASSERT(i < RegCount, "Register index is out of range!");
return regs_[i];
}
auto reg(size_t i) const noexcept -> const Reg& {
/// Vector register at index.
auto reg(this auto&& self, size_t i) noexcept -> auto&& {
TIT_ASSERT(i < RegCount, "Register index is out of range!");
return regs_[i];
return std::forward_like<decltype(self)>(self.regs_[i]);
}
/// @}

// NOLINTEND(*-type-union-access)

Expand Down
33 changes: 8 additions & 25 deletions source/tit/core/_vec/vec_mask.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include <array>
#include <concepts>
#include <utility>

#include "tit/core/basic_types.hpp"
#include "tit/core/checks.hpp"
Expand Down Expand Up @@ -41,16 +42,10 @@ class VecMask final {
: col_{make_array<Dim, bool>(std::forward<Args>(bs)...)} {}

/// Vector mask element at index.
/// @{
constexpr auto operator[](size_t i) noexcept -> bool& {
constexpr auto operator[](this auto&& self, size_t i) noexcept -> auto&& {
TIT_ASSERT(i < Dim, "Row index is out of range!");
return col_[i];
return std::forward_like<decltype(self)>(self.col_[i]);
}
constexpr auto operator[](size_t i) const noexcept -> bool {
TIT_ASSERT(i < Dim, "Row index is out of range!");
return col_[i];
}
/// @}

/// Check if all elements are true.
constexpr operator bool() const noexcept {
Expand Down Expand Up @@ -150,28 +145,16 @@ class VecMask<Num, Dim> final {
constexpr ~VecMask() = default;

/// Vector mask element at index.
/// @{
constexpr auto operator[](size_t i) noexcept -> Mask& {
TIT_ASSERT(i < Dim, "Row index is out of range.");
return col_[i];
}
constexpr auto operator[](size_t i) const noexcept -> const Mask& {
TIT_ASSERT(i < Dim, "Row index is out of range.");
return col_[i];
constexpr auto operator[](this auto&& self, size_t i) noexcept -> auto&& {
TIT_ASSERT(i < Dim, "Row index is out of range!");
return std::forward_like<decltype(self)>(self.col_[i]);
}
/// @}

/// Underlying register at index.
/// @{
auto reg(size_t i) noexcept -> RegMask& {
TIT_ASSERT(i < RegCount, "Register index is out of range.");
return regs_[i];
}
auto reg(size_t i) const noexcept -> const RegMask& {
auto reg(this auto&& self, size_t i) noexcept -> auto&& {
TIT_ASSERT(i < RegCount, "Register index is out of range.");
return regs_[i];
return std::forward_like<decltype(self)>(self.regs_[i]);
}
/// @}

// NOLINTEND(*-type-union-access)

Expand Down
47 changes: 10 additions & 37 deletions source/tit/core/containers/mdvector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,44 +161,24 @@ class Mdvector {
}

/// Iterator pointing to the first vector element.
/// @{
constexpr auto begin() noexcept {
return vals_.begin();
constexpr auto begin(this auto& self) noexcept {
return self.vals_.begin();
}
constexpr auto begin() const noexcept {
return vals_.begin();
}
/// @}

/// Iterator pointing to the element after the last vector element.
/// @{
constexpr auto end() noexcept {
return vals_.end();
}
constexpr auto end() const noexcept {
return vals_.end();
constexpr auto end(this auto& self) noexcept {
return self.vals_.end();
}
/// @}

/// Reference to the first span element.
/// @{
constexpr auto front() noexcept -> Val& {
return vals_.front();
constexpr auto front(this auto&& self) noexcept -> auto&& {
return std::forward_like<decltype(self)>(self.vals_.front());
}
constexpr auto front() const noexcept -> const Val& {
return vals_.front();
}
/// @}

/// Reference to the last span element.
/// @{
constexpr auto back() noexcept -> Val& {
return vals_.back();
}
constexpr auto back() const noexcept -> const Val& {
return vals_.back();
constexpr auto back(this auto&& self) noexcept -> auto&& {
return std::forward_like<decltype(self)>(self.vals_.back());
}
/// @}

/// Clear the vector.
constexpr void clear() noexcept {
Expand All @@ -216,19 +196,12 @@ class Mdvector {
}

/// Reference to vector element or sub-vector span.
/// @{
template<class... Indices>
requires mdindex<Rank, Indices...>
constexpr auto operator[](Indices... indices) noexcept -> decltype(auto) {
return Mdspan{shape_, vals_}[indices...];
}
template<class... Indices>
requires mdindex<Rank, Indices...>
constexpr auto operator[](Indices... indices) const noexcept
constexpr auto operator[](this auto& self, Indices... indices) noexcept
-> decltype(auto) {
return Mdspan{shape_, vals_}[indices...];
return Mdspan{self.shape_, self.vals_}[indices...];
}
/// @}

private:

Expand Down
37 changes: 8 additions & 29 deletions source/tit/core/containers/multivector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,19 +66,11 @@ class Multivector {
}

/// Bucket of values at index.
/// @{
constexpr auto operator[](size_t index) noexcept -> std::span<Val> {
TIT_ASSERT(index < size(), "Bucket index is out of range!");
return {vals_.begin() + val_ranges_[index],
vals_.begin() + val_ranges_[index + 1]};
constexpr auto operator[](this auto& self, size_t index) noexcept {
TIT_ASSERT(index < self.size(), "Bucket index is out of range!");
return std::span{self.vals_.begin() + self.val_ranges_[index],
self.vals_.begin() + self.val_ranges_[index + 1]};
}
constexpr auto operator[](size_t index) const noexcept
-> std::span<const Val> {
TIT_ASSERT(index < size(), "Bucket index is out of range!");
return {vals_.begin() + val_ranges_[index],
vals_.begin() + val_ranges_[index + 1]};
}
/// @}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand All @@ -95,14 +87,7 @@ class Multivector {
std::ranges::range_reference_t<Bucket>>
constexpr void append_bucket(Bucket&& bucket) {
TIT_ASSUME_UNIVERSAL(Bucket, bucket);
#ifndef __clang__
std::ranges::copy(bucket, std::back_inserter(vals_));
#else
/// @todo For some reason, Clang cannot properly optimize the above code.
const auto old_size = vals_.size();
vals_.resize(old_size + bucket.size());
std::ranges::copy(bucket, vals_.begin() + old_size);
#endif
val_ranges_.push_back(vals_.size());
}

Expand Down Expand Up @@ -318,17 +303,11 @@ class CapMultivector {
}

/// Bucket of values at index.
/// @{
constexpr auto operator[](size_t index) noexcept -> std::span<Val> {
TIT_ASSERT(index < size(), "Bucket index is out of range!");
return std::span{buckets_[index]}.subspan(0, bucket_sizes_[index]);
}
constexpr auto operator[](size_t index) const noexcept
-> std::span<const Val> {
TIT_ASSERT(index < size(), "Bucket index is out of range!");
return std::span{buckets_[index]}.subspan(0, bucket_sizes_[index]);
constexpr auto operator[](this auto& self, size_t index) noexcept {
TIT_ASSERT(index < self.size(), "Bucket index is out of range!");
return std::span{self.buckets_[index]} //
.subspan(0, self.bucket_sizes_[index]);
}
/// @}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down
5 changes: 3 additions & 2 deletions source/tit/core/numbers/strict.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#pragma once

#include <concepts>
#include <utility>

#include "tit/core/math.hpp"

Expand Down Expand Up @@ -33,8 +34,8 @@ class Strict final {
constexpr explicit Strict(Num val) : val_{val} {}

/// Get the underlying value.
constexpr auto get(this auto& self) noexcept -> auto& {
return self.val_;
constexpr auto get(this auto&& self) noexcept -> auto&& {
return std::forward<decltype(self)>(self).val_;
}

/// Cast number to a different type.
Expand Down
10 changes: 2 additions & 8 deletions source/tit/sph/field.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,16 +176,10 @@ class PartVec final {
/// @}

/// Get the partition index at the specified level.
/// @{
constexpr auto operator[](size_t i) const noexcept -> PartIndex {
TIT_ASSERT(i < MaxNumLevels, "Level index is out of range!");
return vec_[i];
}
constexpr auto operator[](size_t i) noexcept -> PartIndex& {
constexpr auto operator[](this auto&& self, size_t i) noexcept -> auto&& {
TIT_ASSERT(i < MaxNumLevels, "Level index is out of range!");
return vec_[i];
return std::forward_like<decltype(self)>(self.vec_[i]);
}
/// @}

/// Find the last assigned partition index.
constexpr auto last() const noexcept -> PartIndex {
Expand Down

0 comments on commit c6d9edd

Please sign in to comment.