-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
define canonical form for blade types
Change-Id: If2396afbe3d57b84214445eb6728e660dc6c313a
- Loading branch information
Showing
6 changed files
with
225 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
#pragma once | ||
|
||
#include "rigid_geometric_algebra/detail/unique_dimensions.hpp" | ||
|
||
#include <cstddef> | ||
#include <tuple> | ||
#include <type_traits> | ||
|
||
namespace rigid_geometric_algebra { | ||
namespace detail { | ||
|
||
inline constexpr class | ||
{ | ||
template <std::size_t N> | ||
using constant = std::integral_constant<std::size_t, N>; | ||
|
||
template <std::size_t N, class... Is> | ||
static constexpr auto make_sequence_from(Is... is) | ||
{ | ||
if constexpr (((N > Is::value) and ...)) { | ||
return std::tuple{}; | ||
} else if constexpr (((N == Is::value) or ...)) { | ||
return std::tuple_cat( | ||
std::tuple<constant<N>>{}, make_sequence_from<N + 1>(is...)); | ||
} else { | ||
return make_sequence_from<N + 1>(is...); | ||
} | ||
} | ||
|
||
public: | ||
constexpr auto operator()() const noexcept { return std::index_sequence<>{}; } | ||
|
||
template <class... Is> | ||
constexpr auto operator()(Is... is) const noexcept | ||
{ | ||
return []<class... Js>( | ||
std::tuple<Js...>) -> std::index_sequence<Js::value...> { | ||
return {}; | ||
}(make_sequence_from<0>(is...)); | ||
} | ||
|
||
} sort_dimensions_impl{}; | ||
|
||
template <std::size_t... Is> | ||
requires (unique_dimensions<Is...>()) | ||
struct sorted_dimensions | ||
: decltype(sort_dimensions_impl( | ||
std::integral_constant<std::size_t, Is>{}...)){}; | ||
|
||
} // namespace detail | ||
} // namespace rigid_geometric_algebra |
67 changes: 67 additions & 0 deletions
67
rigid_geometric_algebra/detail/swaps_to_sorted_dimensions.hpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
#pragma once | ||
|
||
#include "rigid_geometric_algebra/detail/sorted_dimensions.hpp" | ||
#include "rigid_geometric_algebra/detail/unique_dimensions.hpp" | ||
|
||
#include <algorithm> | ||
#include <array> | ||
#include <cassert> | ||
#include <cstddef> | ||
#include <iterator> | ||
#include <ranges> | ||
#include <type_traits> | ||
|
||
namespace rigid_geometric_algebra { | ||
namespace detail { | ||
|
||
template <std::size_t... Is> | ||
class swaps_to_sorted_dimensions_fn | ||
{ | ||
template < | ||
std::ranges::random_access_range R1, | ||
std::ranges::random_access_range R2> | ||
requires std::ranges::view<R1> and std::ranges::view<R2> | ||
static constexpr auto impl(R1 unsorted, R2 sorted) -> std::size_t | ||
{ | ||
assert(unsorted.size() == sorted.size()); | ||
|
||
if (unsorted.empty()) { | ||
return 0UZ; | ||
} | ||
|
||
if (unsorted.size() == 1) { | ||
assert(unsorted.front() == sorted.front()); | ||
return 0Uz; | ||
} | ||
|
||
auto it = std::ranges::find(unsorted, sorted.front()); | ||
assert(it != unsorted.end()); | ||
std::iter_swap(it, unsorted.begin()); | ||
|
||
return std::size_t(it != unsorted.begin()) + | ||
impl(unsorted | std::views::drop(1), sorted | std::views::drop(1)); | ||
} | ||
|
||
public: | ||
constexpr auto operator()() const noexcept -> std::size_t | ||
{ | ||
assert(unique_dimensions<Is...>()); | ||
|
||
constexpr auto into_array = | ||
[]<std::size_t... Js>(std::index_sequence<Js...>) { | ||
return std::array<std::size_t, sizeof...(Js)>{Js...}; | ||
}; | ||
|
||
auto unsorted = into_array(std::index_sequence<Is...>{}); | ||
const auto sorted = into_array(sorted_dimensions<Is...>{}); | ||
|
||
return impl(std::ranges::subrange(unsorted), std::ranges::subrange(sorted)); | ||
} | ||
}; | ||
|
||
template <std::size_t... Is> | ||
inline constexpr auto swaps_to_sorted_dimensions = | ||
swaps_to_sorted_dimensions_fn<Is...>{}; | ||
|
||
} // namespace detail | ||
} // namespace rigid_geometric_algebra |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters