Line data Source code
1 1 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <cstddef>
7 : #include <type_traits>
8 :
9 : #include "DataStructures/Tensor/Expressions/TensorIndex.hpp"
10 : #include "DataStructures/Tensor/IndexType.hpp"
11 : #include "DataStructures/Tensor/Symmetry.hpp"
12 : #include "Utilities/Algorithm.hpp"
13 : #include "Utilities/ConstantExpressions.hpp"
14 : #include "Utilities/Gsl.hpp"
15 : #include "Utilities/Requires.hpp"
16 : #include "Utilities/TMPL.hpp"
17 :
18 : /// \file
19 : /// Defines functions and metafunctions used for helping evaluate
20 : /// TensorExpression equations where concrete time indices are used for
21 : /// spacetime indices
22 :
23 : namespace tt {
24 : /// \ingroup TypeTraitsGroup TensorExpressionsGroup
25 : /// \brief Check if a type `T` is a TensorIndex representing a concrete time
26 : /// index
27 : template <typename T>
28 1 : struct is_time_index : std::false_type {};
29 : template <>
30 : struct is_time_index<std::decay_t<decltype(ti::t)>> : std::true_type {};
31 : template <>
32 : struct is_time_index<std::decay_t<decltype(ti::T)>> : std::true_type {};
33 : } // namespace tt
34 :
35 : namespace tenex {
36 : namespace detail {
37 : /// \brief Returns whether or not the provided value is the TensorIndex value
38 : /// that encodes the upper or lower concrete time index (`ti::T` or `ti::t`)
39 : ///
40 : /// \param value the value to check
41 : /// \return whether or not the value encodes the upper or lower concrete time
42 : /// index
43 : constexpr bool is_time_index_value(const size_t value) {
44 : return value == ti::t.value or value == ti::T.value;
45 : }
46 :
47 : template <typename State, typename Element>
48 : struct remove_time_indices_impl {
49 : using type =
50 : typename std::conditional_t<not tt::is_time_index<Element>::value,
51 : tmpl::push_back<State, Element>, State>;
52 : };
53 :
54 : /// \brief Given a TensorIndex list, returns the TensorIndex list with time
55 : /// indices removed
56 : ///
57 : /// \tparam TensorIndexList the generic index list
58 : template <typename TensorIndexList>
59 : struct remove_time_indices {
60 : using type =
61 : tmpl::fold<TensorIndexList, tmpl::list<>,
62 : remove_time_indices_impl<tmpl::_state, tmpl::_element>>;
63 : };
64 :
65 : template <typename State, typename Element, typename Iteration>
66 : struct time_index_positions_impl {
67 : using type =
68 : typename std::conditional_t<tt::is_time_index<Element>::value,
69 : tmpl::push_back<State, Iteration>, State>;
70 : };
71 :
72 : /// \brief Given a TensorIndex list, returns the list of positions of concrete
73 : /// time indices
74 : ///
75 : /// \tparam TensorIndexList the TensorIndex list
76 : template <typename TensorIndexList>
77 : using time_index_positions = tmpl::enumerated_fold<
78 : TensorIndexList, tmpl::list<>,
79 : time_index_positions_impl<tmpl::_state, tmpl::_element, tmpl::_3>,
80 : tmpl::size_t<0>>;
81 :
82 : /// \brief Given a TensorIndex list, returns the list of positions of concrete
83 : /// time indices
84 : ///
85 : /// \tparam TensorIndexList the TensorIndex list
86 : /// \return the list of positions of concrete time indices
87 : template <typename TensorIndexList>
88 : constexpr auto get_time_index_positions() {
89 : using time_index_positions_ = time_index_positions<TensorIndexList>;
90 : using make_list_type =
91 : std::conditional_t<tmpl::size<time_index_positions_>::value == 0, size_t,
92 : time_index_positions_>;
93 : return make_array_from_list<make_list_type>();
94 : }
95 : } // namespace detail
96 : } // namespace tenex
|