Lumiera 0.pre.04~rc.1
»edit your freedom«
Loading...
Searching...
No Matches
tuple-closure.hpp
Go to the documentation of this file.
1/*
2 TUPLE-CLOSURE.hpp - metaprogramming tools for tuple-likes with partial closure
3
4 Copyright (C)
5 2025, Hermann Vosseler <Ichthyostega@web.de>
6
7  **Lumiera** is free software; you can redistribute it and/or modify it
8  under the terms of the GNU General Public License as published by the
9  Free Software Foundation; either version 2 of the License, or (at your
10  option) any later version. See the file COPYING for further details.
11
12*/
13
14
43#ifndef LIB_META_TUPLE_CLOSURE_H
44#define LIB_META_TUPLE_CLOSURE_H
45
48#include "lib/util.hpp"
49
50#include <utility>
51#include <tuple>
52#include <array>
53
54
55
56namespace lib {
57namespace meta{
58
59 using std::move;
60 using util::unConst;
61
68 template<class PAR>
70 {
71 static_assert (!sizeof(PAR),
72 "attempt to partially close something not tuple-like");
73 };
74
75 template<template<typename...> class TUP, typename...PARS>
76 struct TupleClosureBuilder<TUP<PARS...>>
77 {
78 static_assert (sizeof...(PARS)
79 ,"attempt to partially close empty record");
80
81 using Tuple = TUP<PARS...>;
83
85 static Tuple
87 {
88 return {std::move(params)...};
89 }
90
93 template<typename...VALS>
94 static auto
96 {
98 auto boundArgs = std::make_tuple (std::forward<VALS> (vs)...); // Note: must be passed by-val here
99 return wrapBuilder (func::PApply<TupleBuilderSig, ClosedTypes>::bindFront (buildRecord, move(boundArgs)));
100 }
101
104 template<typename...VALS>
105 static auto
107 {
109 auto boundArgs = std::make_tuple (std::forward<VALS> (vs)...);
110 return wrapBuilder (func::PApply<TupleBuilderSig, ClosedTypes>::bindBack (buildRecord, move(boundArgs)));
111 }
112
115 template<size_t idx, typename VAL>
116 static auto
117 close (VAL&& val)
118 {
119 using BoundVal = std::decay_t<VAL>;
120 return wrapBuilder (func::BindToArgument<TupleBuilderSig,BoundVal,idx>::reduced (buildRecord, std::forward<VAL>(val)));
121 }
122
123 template<size_t idx, typename VAL>
124 static auto
125 closett (VAL&& val)
126 {
127 using BoundVal = std::decay_t<VAL>;
128 return wrapBuilder (func::BindToArgument<TupleBuilderSig,BoundVal,idx>::refused (buildRecord, std::forward<VAL>(val)));
129 }
130
131 private:
132 template<class CLO>
133 static auto
135 {
136 using RemainingArgs = _Fun<CLO>::Args;
138
139 struct Wrap
140 {
141 auto
143 {
144 return lib::meta::apply (unConst(this)->partialClosure_, remPar);
145 };
146
148 }; // Note: need a single operator() which works also for const
149 // can not do this with a λ
150 return Wrap{move(closureFun)};
151 }
152 };
153
154
155
156 /* ===== adapt array for tuple-like signature ===== */
157
162 template<typename...TTT>
164 {
165 static_assert(sizeof...(TTT)
166 ,"empty list ... attempting total (not partial) closure?");
167 };
168
169
171 template<typename...TTT>
172 struct AllSame
173 : std::true_type // trivially true for empty conjunction and single element
174 { };
175
176 template<typename T1, typename T2, typename...TS>
177 struct AllSame<T1,T2,TS...>
178 : __and_<is_same<T1,T2>
179 ,AllSame<T2,TS...>
180 >
181 { };
182
183
184 namespace {
186 template<typename T, size_t N>
187 struct _Adapt
188 {
191 static_assert(N,"attempt to partially close empty array");
192 };
193
194 template<typename T, size_t N>
196 }
197
199 template<typename T, typename...TT>
200 struct ArrayAdapt<T,TT...>
201 : std::array<T, 1+sizeof...(TT)>
202 {
203 static_assert (AllSame<T,TT...>()
204 ,"Array can only hold elements of uniform type");
205 using Array = std::array<T, 1+sizeof...(TT)>;
206
207
208 ArrayAdapt (Array const& o) : Array{o} { }
209 ArrayAdapt (Array && r) : Array{move(r)} { }
210
211 template<typename...XS>
213 : Array{std::forward<XS> (inits)...}
214 { }
215 };
216
217 template<typename...TTT>
219
220
221
226 template<typename T, size_t N>
227 struct TupleClosureBuilder<std::array<T,N>>
228 : TupleClosureBuilder<_AdaptArray_t<T,N>>
229 {
230 };
231
232
233}} // namespace lib::meta
234
235
236namespace std { // Specialisation to support C++ »Tuple Protocol« and structured bindings.
237
239 template<typename...TTT>
240 struct tuple_size<lib::meta::ArrayAdapt<TTT...> >
241 : integral_constant<size_t, sizeof...(TTT)>
242 { };
243
245 template<size_t I, typename...TTT>
246 struct tuple_element<I, lib::meta::ArrayAdapt<TTT...> >
247 : tuple_element<I, typename lib::meta::ArrayAdapt<TTT...>::Array>
248 { };
249
250 // Note: the std::get<i> function will pick the baseclass anyway
251}
252#endif /*LIB_META_TUPLE_CLOSURE_H*/
Bind a specific argument to an arbitrary value.
Partial function application Takes a function and a value tuple, using the latter to close function a...
Partial function application and building a complete function closure.
RebindVariadic< ArrayAdapt, NFold >::Type Array
BuildTupleType< TYPES >::Type Tuple
Build a std::tuple from types given as type sequence.
enable_if_c< Cond::value, T >::type enable_if
SFINAE helper to control the visibility of specialisations and overloads.
Definition meta/util.hpp:87
constexpr decltype(auto) apply(FUN &&f, TUP &&tup) noexcept(can_nothrow_invoke_tup< FUN, TUP >)
Replacement for std::apply — yet applicable to tuple-like custom types.
Prepend< T, Rem >::Seq Seq
Metaprogramming adapter to overlay a tuple-like signature on top of std::array, with N times the same...
Metaprogramming helper to build a constructor-function for »tuple-like« records, where some of the in...
Implementation namespace for support and library code.
STL namespace.
OBJ * unConst(const OBJ *)
shortcut to save some typing when having to define const and non-const variants of member functions
Definition util.hpp:358
Metafunction to detect if a type-sequence holds uniform types.
std::array< T, 1+sizeof...(TT)> Array
static auto closeFront(VALS &&...vs)
preconfigure some elements to the given values, starting from left
static auto close(VAL &&val)
preconfigure element to the given value
static auto closeBack(VALS &&...vs)
preconfigure some elements to the given values, in forward order yet aligned to the tuple end
static Tuple buildRecord(PARS ...params)
the builder function to be partially closed
Trait template for uniform access to function signature types.
Definition function.hpp:144
Metaprogramming with tuples-of-types and the std::tuple record.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...