lumiera_/tests/library/meta/tuple-closure-test.cpp
Ichthyostega a5a3d46b6a Invocation: generalise partial-closure cases
With these additions, all conceivable cases are basically addressed.

Take this as opportunity to investigate how the existing implementation
transports values into the Binder, where they will be stored as data fields.
Notably the mechanism of the `TupleConstructor` / `ElmMapper` indeed
''essentially requires'' to pass the initialisers ''by-reference'',
because otherwise there would be limitations on possible mappings.

This implies that not much can be done for ''perfect forwarding'' of initialisers,
but at least the `BindToArgument` can be simplified to take the value directly.
2025-02-17 21:18:37 +01:00

145 lines
4.5 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
TupleClosure(Test) - appending, mixing and filtering typelists
Copyright (C)
2025, Hermann Vosseler <Ichthyostega@web.de>
  **Lumiera** is free software; you can redistribute it and/or modify it
  under the terms of the GNU General Public License as published by the
  Free Software Foundation; either version 2 of the License, or (at your
  option) any later version. See the file COPYING for further details.
* *****************************************************************/
/** @file function-closure-test.cpp
** Unit test \ref TupleClosure_test demonstrates how to pre-bind
** some values for construction of _tuple-like_ objects.
** @see function-closure.hpp
** @see NodeBuilder_test::build_Node_closedParam() "usage example"
**
*/
#include "lib/test/run.hpp"
#include "lib/test/test-helper.hpp"
#include "lib/meta/tuple-closure.hpp"
#include "lib/format-util.hpp"
#include "lib/test/diagnostic-output.hpp"////////////////TODO
namespace lib {
namespace meta {
namespace test {
using std::string;
using std::tuple;
using std::array;
using std::make_tuple;
using lib::meta::_Fun;
using lib::test::showType;
/*********************************************************************//**
* @test wrap the constructors for »tuple-like« records as functor
* and pre-bind some arguments immediately.
*/
class TupleClosure_test : public Test
{
virtual void
run (Arg)
{
tuple_bindFront();
tuple_bindBack();
tuple_bindArg();
array_bindFront();
}
/** @test use a regular tuple and pre-fix the first elements
*/
void
tuple_bindFront()
{
using Tup = tuple<int,double,string>;
using Builder = TupleClosureBuilder<Tup>;
auto cons = Builder::closeFront (1,2.3);
using FunType = _Fun<decltype(cons)>;
CHECK (FunType() == true); // indeed a function
CHECK (showType<FunType::Sig>() == "tuple<int, double, string> (tuple<string>)"_expect);
Tup tup = cons("five");
CHECK (tup == "«tuple<int, double, string>»──(1,2.3,five)"_expect);
}
/** @test fix elements starting from the end of the tuple
*/
void
tuple_bindBack()
{
using Tup = tuple<int,double,string>;
using Builder = TupleClosureBuilder<Tup>;
auto c1 = Builder::closeBack("π");
CHECK (showType<_Fun<decltype(c1)>::Sig>() == "tuple<int, double, string> (tuple<int, double>)"_expect);
Tup t1 = c1(make_tuple (2,3.1415));
CHECK (t1 == "«tuple<int, double, string>»──(2,3.1415,π)"_expect);
auto c2 = Builder::closeBack(3.14159265,"pi");
CHECK (showType<_Fun<decltype(c2)>::Sig>() == "tuple<int, double, string> (tuple<int>)"_expect);
Tup t2 = c2(make_tuple (-1));
CHECK (t2 == "«tuple<int, double, string>»──(-1,3.1415927,pi)"_expect);
}
/** @test fix specific argument within tuple
*/
void
tuple_bindArg()
{
using Tup = tuple<int,double,string>;
using Builder = TupleClosureBuilder<Tup>;
auto c1 = Builder::close<1>(3.1415927);
CHECK (showType<_Fun<decltype(c1)>::Sig>() == "tuple<int, double, string> (tuple<int, string>)"_expect);
Tup t1 = c1({2,"π"});
CHECK (t1 == "«tuple<int, double, string>»──(2,3.1415927,π)"_expect);
auto c2 = Builder::close<3>("fantastic");
// Binding to out-of-scope arguments is ignored: the result is the identity-function
CHECK (showType<_Fun<decltype(c2)>::Sig>() == "tuple<int, double, string> (tuple<int, double, string>)"_expect);
}
/** @test use a std::array and handle it like a tuple to pre-fix some elements
*/
void
array_bindFront()
{
using Arr = array<int,5>;
using Builder = TupleClosureBuilder<Arr>;
auto cons = Builder::closeFront (1u,2.3);
using FunType = _Fun<decltype(cons)>;
CHECK (showType<FunType::Sig>() == "ArrayAdapt<int, int, int, int, int> (ArrayAdapt<int, int, int>)"_expect);
Arr arr = cons({3,4,5});
CHECK (arr == "[1, 2, 3, 4, 5]"_expect);
}
};
/** Register this test class... */
LAUNCHER (TupleClosure_test, "unit common");
}}} // namespace lib::meta::test