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