mirror of
https://github.com/ETLCPP/etl.git
synced 2026-05-01 03:19:10 +08:00
* topic/expected-monadic-operations: - added and_then, or_else, transform, and transform_error with simple tests * topic/expected-monadic-operation: - added void TValue specialization operations - updated unit tests to include expected<void, TError> - added is_expected to expected.h, used in and_then to ensure that the returned type is an expected * topic/expected-monadic-operations: - made implementation c++11 compatible * topic/expected-monadic-operations: - started addressing coderabbit feedback * topic/expected-monadic-operations: - adapted invoke to etl - reworked return type deduction - filled in or_else unit tests to be more complete - still need to add invoke unit tests * topic/expected-monadic-operations: -c++14 compliance * topic/expected-monadic-operations: - completed coderabbit suggestions * topic/expected-monadic-operations: - formatting in invoke and expected - added test suite for invoke * topic/expected-monadic-operations: - fixed missing moves for const TValue&& and const TError&& * topic/expected-monadic-operations: - made everything c++11 compatible, very verbose as a result * topic/expected-monadic-operations: - fixed code rabbit rewivew for move semantics in const && overloads * topic/expected-monadic-operations: - moved around a move * topic/expected-monadic-operations: - added etl:: to invoke_result calls that were missing it * topic/expected-monadic-operations: - formatting * topic/expected-monadic-operations: - added invoke for void f() calls for consistency * topic/expected-monadic-operations: - reworked entire thing to be able to handle expected<T,E> to expected<void,E> without even more code duplication * topic/expected-monadic-operations: - added trailing return type to maintain c++11 compatibility * topic/expected-monadic-operations: - fixed mismatch between deduced type and return for a few functions * topic/expected-monadic-operations: - replaced calls to get<TError> and get<TValue> with get<Error_Type> and get<Value_Type> --------- Co-authored-by: Jon Whitfield <jon@volumetrix.com>
184 lines
5.8 KiB
C++
184 lines
5.8 KiB
C++
/******************************************************************************
|
|
The MIT License(MIT)
|
|
|
|
Embedded Template Library.
|
|
https://github.com/ETLCPP/etl
|
|
https://www.etlcpp.com
|
|
|
|
Copyright(c) 2025 John Wellbelove
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
of this software and associated documentation files(the "Software"), to deal
|
|
in the Software without restriction, including without limitation the rights
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
furnished to do so, subject to the following conditions :
|
|
|
|
The above copyright notice and this permission notice shall be included in all
|
|
copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
SOFTWARE.
|
|
******************************************************************************/
|
|
|
|
#include "unit_test_framework.h"
|
|
|
|
#include "etl/invoke.h"
|
|
#include <etl/type_traits.h>
|
|
|
|
namespace
|
|
{
|
|
struct TestClass
|
|
{
|
|
int member_obj = 42;
|
|
std::string member_str = "hello";
|
|
|
|
int get_int()
|
|
{
|
|
return member_obj;
|
|
}
|
|
|
|
int const_get_int() const
|
|
{
|
|
return member_obj + 10;
|
|
}
|
|
void set_int(int v)
|
|
{
|
|
member_obj = v;
|
|
}
|
|
static int static_func(int x)
|
|
{
|
|
return x * 2;
|
|
}
|
|
};
|
|
|
|
int standalone_func(int a, int b)
|
|
{
|
|
return a + b;
|
|
}
|
|
|
|
struct Functor
|
|
{
|
|
int operator()(int x) const
|
|
{
|
|
return x * 5;
|
|
}
|
|
};
|
|
|
|
SUITE(test_invoke)
|
|
{
|
|
//*************************************************************************
|
|
TEST(test_type_traits_functions)
|
|
{
|
|
CHECK_TRUE(etl::is_function<int(int)>::value);
|
|
CHECK_TRUE(!etl::is_function<int>::value);
|
|
CHECK_TRUE(!etl::is_function<int*>::value);
|
|
CHECK_TRUE(!etl::is_function<int&>::value);
|
|
CHECK_TRUE(!etl::is_function<int&&>::value);
|
|
CHECK_TRUE(!etl::logical_not_t<etl::true_type>::value);
|
|
CHECK_TRUE(etl::logical_not_t<etl::false_type>::value);
|
|
}
|
|
|
|
//*************************************************************************
|
|
TEST(test_type_traits_member_pointers)
|
|
{
|
|
using MemObjPtr = int TestClass::*;
|
|
using MemFnPtr = int (TestClass::*)();
|
|
|
|
CHECK_TRUE(etl::is_member_pointer<MemObjPtr>::value);
|
|
CHECK_TRUE(etl::is_member_pointer<MemFnPtr>::value);
|
|
CHECK_TRUE(!etl::is_member_pointer<int*>::value);
|
|
|
|
CHECK_TRUE(etl::is_member_object_pointer<MemObjPtr>::value);
|
|
CHECK_TRUE(!etl::is_member_object_pointer<MemFnPtr>::value);
|
|
|
|
CHECK_TRUE(!etl::is_member_function_pointer<MemObjPtr>::value);
|
|
CHECK_TRUE(etl::is_member_function_pointer<MemFnPtr>::value);
|
|
}
|
|
|
|
//*************************************************************************
|
|
TEST(test_invoke_callable)
|
|
{
|
|
CHECK_EQUAL(30, etl::invoke(standalone_func, 10, 20));
|
|
|
|
auto lambda = [](int x)
|
|
{ return x * 3; };
|
|
CHECK_EQUAL(15, etl::invoke(lambda, 5));
|
|
|
|
Functor f;
|
|
CHECK_EQUAL(60, etl::invoke(f, 12));
|
|
|
|
CHECK_EQUAL(8, etl::invoke(TestClass::static_func, 4));
|
|
}
|
|
|
|
//*************************************************************************
|
|
TEST(test_invoke_mem_func_ptr)
|
|
{
|
|
TestClass obj;
|
|
TestClass* ptr = &obj;
|
|
const TestClass const_obj;
|
|
|
|
CHECK_EQUAL(42, etl::invoke(&TestClass::get_int, obj));
|
|
CHECK_EQUAL(42, etl::invoke(&TestClass::get_int, ptr));
|
|
CHECK_EQUAL(52, etl::invoke(&TestClass::const_get_int, const_obj));
|
|
|
|
etl::invoke(&TestClass::set_int, obj, 99);
|
|
CHECK_EQUAL(99, obj.member_obj);
|
|
|
|
etl::invoke(&TestClass::set_int, ptr, 101);
|
|
CHECK_EQUAL(101, ptr->member_obj);
|
|
}
|
|
|
|
//*************************************************************************
|
|
TEST(test_invoke_mem_obj_ptr)
|
|
{
|
|
TestClass obj;
|
|
TestClass* ptr = &obj;
|
|
|
|
CHECK_EQUAL(42, etl::invoke(&TestClass::member_obj, obj));
|
|
CHECK_EQUAL(42, etl::invoke(&TestClass::member_obj, ptr));
|
|
CHECK_EQUAL("hello", etl::invoke(&TestClass::member_str, obj));
|
|
|
|
etl::invoke(&TestClass::member_obj, obj) = 1000;
|
|
CHECK_EQUAL(1000, obj.member_obj);
|
|
|
|
etl::invoke(&TestClass::member_obj, ptr) = 2000;
|
|
CHECK_EQUAL(2000, ptr->member_obj);
|
|
}
|
|
|
|
//*************************************************************************
|
|
TEST(test_invoke_result_t)
|
|
{
|
|
using MemFnPtr = decltype(&TestClass::get_int);
|
|
using ConstMemFnPtr = decltype(&TestClass::const_get_int);
|
|
using MemObjPtr_int = decltype(&TestClass::member_obj);
|
|
using FnPtr = int (*)(int, int);
|
|
|
|
auto val = etl::is_same<etl::invoke_result_t<FnPtr, int, int>, int>::value;
|
|
CHECK_TRUE(val);
|
|
|
|
val = etl::is_same<etl::invoke_result_t<MemFnPtr, TestClass&>, int>::value;
|
|
CHECK_TRUE(val);
|
|
|
|
val = etl::is_same<etl::invoke_result_t<MemFnPtr, TestClass*>, int>::value;
|
|
CHECK_TRUE(val);
|
|
|
|
val = etl::is_same<etl::invoke_result_t<ConstMemFnPtr, const TestClass&>, int>::value;
|
|
CHECK_TRUE(val);
|
|
|
|
val = etl::is_same<etl::invoke_result_t<MemObjPtr_int, TestClass&>, int&>::value;
|
|
CHECK_TRUE(val);
|
|
|
|
val = etl::is_same<etl::invoke_result_t<MemObjPtr_int, const TestClass&>, const int&>::value;
|
|
CHECK_TRUE(val);
|
|
|
|
val = etl::is_same<etl::invoke_result_t<MemObjPtr_int, TestClass*>, int&>::value;
|
|
CHECK_TRUE(val);
|
|
}
|
|
}
|
|
} |