Bertini 2 d882924 (2026-10-06 19:56 UTC)
Numerical algebraic geometry library (C++ core)
Loading...
Searching...
No Matches
enable_permuted_arguments.hpp
Go to the documentation of this file.
1//This file is part of Bertini 2.
2//
3//enable_permuted_arguments.hpp is free software: you can redistribute it and/or modify
4//it under the terms of the GNU General Public License as published by
5//the Free Software Foundation, either version 3 of the License, or
6//(at your option) any later version.
7//
8//enable_permuted_arguments.hpp is distributed in the hope that it will be useful,
9//but WITHOUT ANY WARRANTY; without even the implied warranty of
10//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11//GNU General Public License for more details.
12//
13//You should have received a copy of the GNU General Public License
14//along with enable_permuted_arguments.hpp. If not, see <http://www.gnu.org/licenses/>.
15//
16// Copyright(C) Bertini2 Development Team
17//
18// See <http://www.gnu.org/licenses/> for a copy of the license,
19// as well as COPYING. Bertini2 is provided with permitted
20// additional terms in the b2/licenses/ directory.
21
29
30#ifndef BERTINI_ENABLE_PERMUTED_ARGUMENTS
31#define BERTINI_ENABLE_PERMUTED_ARGUMENTS
32
33#include <type_traits>
34#include <tuple>
35
36
37namespace bertini {
38
39
40 namespace detail {
41 // find the index of a type in a list of types,
42 // return sizeof...(Remaining) if T is not found
43 template< typename T, typename... Remaining >
44 struct IndexByType : std::integral_constant< std::size_t, 0 >
45 {};
46
47 // template specialization, enforcing the equality of the number of variadic arguments, and the corresponding index.
48 // if two types are the same, this template will be preferred since it's a closer match, and the static_assert will fail, preventing compilation.
49 template< typename T, typename... RemainingT >
50 struct IndexByType< T, T, RemainingT... > : std::integral_constant< std::size_t, 0 >
51 {
52 static_assert( IndexByType< T, RemainingT... >::value == sizeof...( RemainingT ), "No duplicates are allowed when enabling permuted arguments" );
53 };
54
55 // template specialization on two types. looks for the index of T in the latter arguments. If T1==T2, this template will not be used, but instead the above will.
56 template< typename T1, typename T2, typename... RemainingT >
57 struct IndexByType< T1, T2, RemainingT... > : std::integral_constant< std::size_t, IndexByType< T1, RemainingT... >::value + 1 >
58 {};
59
61 template< std::size_t I, std::size_t J,
62 typename T, typename... PresentT, typename... GivenT >
63 auto GetByIndex( const std::tuple< PresentT... >&,
64 const std::tuple< GivenT... >& absent_args )
65 -> typename std::enable_if< I == sizeof...( PresentT ), const T& >::type
66 {
67 return std::get< J >( absent_args );
68 }
69
71 template< std::size_t I, std::size_t J,
72 typename T, typename... PresentT, typename... GivenT >
73 auto GetByIndex(const std::tuple< PresentT... >& present_args,
74 const std::tuple< GivenT... >& ) // these arguments will have to be default constructed
75 -> typename std::enable_if< I != sizeof...( PresentT ), const T& >::type /* remember, `I != sizeof...( PresentT )` means it found T in PresentT */
76 {
77 return std::get< I >( present_args );
78 }
79
80
81
82
83 // helper to validate that all Us are in Ts...
84 template< bool > struct AreValidArguments;
85
86 // the false one is never instantiated, so the 'false' template parameter will fail, deliberately
87 template<> struct AreValidArguments< true > : std::true_type
88 {};
89
91 template< std::size_t... >
93 {}
94
95
96
98 template< typename T >
100 {
101 static const T value;
102 };
103
105 template< typename T >
107 {};
109
110
111
112 } // namespace detail
113
115 template< typename... UnpermutedT, // these must be declared when using the function
116 typename... PermutedPresentT > // these are inferred, cannot be declared
117 std::tuple< const UnpermutedT&... > Unpermute( const PermutedPresentT&... present_permuted_args )
118 {
119 using namespace detail;
120 auto present_args = std::tie( present_permuted_args... );
121 auto absent_args = std::tie( DefaultConstruct< UnpermutedT >::value... );
122
123 //next we validate that the input arguments are valid for unpermuting. must have all distinct types.
124 ValidateTypes< AreValidArguments< IndexByType< const PermutedPresentT&,
125 const UnpermutedT&... >::value != sizeof...( UnpermutedT )
126 >::value...
127 >(); // this will fail if AreValidArguments are not valid ('true')
128
129 // finally, we return a tie of the unpermuted types, default constructed if necessary
130 return std::tie( GetByIndex< IndexByType< const UnpermutedT&, const PermutedPresentT&... >::value,
131 IndexByType< const UnpermutedT&, const UnpermutedT&... >::value, UnpermutedT >
132 ( present_args, absent_args )... );
133 }
134
135
136} // re: namespace bertini
137
138#endif
Definition configured.hpp:34
auto GetByIndex(const std::tuple< PresentT... > &, const std::tuple< GivenT... > &absent_args) -> typename std::enable_if< I==sizeof...(PresentT), const T & >::type
Get the value of type T, pulling from the given (absent) args when T is not among the present types.
Definition enable_permuted_arguments.hpp:63
void ValidateTypes()
Proxy function ensuring the types are distinct and indexable by type (compile-time check).
Definition enable_permuted_arguments.hpp:92
Definition algorithm_builder.hpp:36
std::tuple< const UnpermutedT &... > Unpermute(const PermutedPresentT &... present_permuted_args)
Reorder a set of present arguments into the declared UnpermutedT order, default-constructing any abse...
Definition enable_permuted_arguments.hpp:117
Definition enable_permuted_arguments.hpp:84
Holds a default-constructed value of T, used to fill arguments not present when unpermuting.
Definition enable_permuted_arguments.hpp:100
static const T value
The default-constructed value of T.
Definition enable_permuted_arguments.hpp:101
Definition enable_permuted_arguments.hpp:45