mirror of
https://github.com/BlackMATov/kari.hpp.git
synced 2025-12-15 05:25:25 +07:00
move common test stuff to kari_tests.hpp
This commit is contained in:
@@ -7,9 +7,66 @@
|
|||||||
#include <kari.hpp/kari_ext.hpp>
|
#include <kari.hpp/kari_ext.hpp>
|
||||||
#include "doctest/doctest.hpp"
|
#include "doctest/doctest.hpp"
|
||||||
|
|
||||||
using namespace kari_hpp;
|
#include "kari_tests.hpp"
|
||||||
|
|
||||||
|
using namespace kari_hpp;
|
||||||
|
using namespace kari_tests;
|
||||||
|
|
||||||
|
TEST_CASE("kari_ext") {
|
||||||
|
SUBCASE("fid") {
|
||||||
|
REQUIRE(fid(box(10)).v() == 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBCASE("fconst") {
|
||||||
|
REQUIRE(fconst(box(10), 20).v() == 10);
|
||||||
|
{
|
||||||
|
auto b10 = fconst(box(10));
|
||||||
|
REQUIRE(b10(20).v() == 10);
|
||||||
|
REQUIRE(std::move(b10)(30).v() == 10);
|
||||||
|
REQUIRE(b10(20).v() == 100500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBCASE("fflip") {
|
||||||
|
REQUIRE(fflip(curry(std::minus<>()))(10, 20) == 10);
|
||||||
|
REQUIRE(fflip(minus3_gl)(10,20,50) == -40);
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBCASE("fpipe") {
|
||||||
|
using namespace underscore;
|
||||||
|
REQUIRE(fpipe(_+2, _*2, 4) == 12);
|
||||||
|
REQUIRE(((_+2) | (_*2) | 4) == 12);
|
||||||
|
REQUIRE((4 | (_+2) | (_*2)) == 12);
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBCASE("fcompose") {
|
||||||
|
using namespace underscore;
|
||||||
|
REQUIRE(fcompose(_+2, _*2, 4) == 10);
|
||||||
|
REQUIRE((_+2) * (_*2) * 4 == 10);
|
||||||
|
REQUIRE(4 * (_+2) * (_*2) == 12);
|
||||||
|
{
|
||||||
|
const auto s3 = [](int v1, int v2, int v3){
|
||||||
|
return v1 + v2 + v3;
|
||||||
|
};
|
||||||
|
const auto c = curry(s3) * (_*2) * 10 * 20 * 30;
|
||||||
|
REQUIRE(c == 70);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// (. (+2)) (*2) $ 10 == 24
|
||||||
|
int i = fflip(fcompose)(_+2, _*2, 10);
|
||||||
|
int j = (_*(_+2))(_*2)(10);
|
||||||
|
REQUIRE(i == 24);
|
||||||
|
REQUIRE(j == 24);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// ((+2) .) (*2) $ 10 == 24
|
||||||
|
int i = fcompose(_+2)(_*2, 10);
|
||||||
|
int j = ((_+2) * _)(_*2)(10);
|
||||||
|
REQUIRE(i == 22);
|
||||||
|
REQUIRE(j == 22);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("kari_feature") {
|
|
||||||
SUBCASE("underscore") {
|
SUBCASE("underscore") {
|
||||||
using namespace underscore;
|
using namespace underscore;
|
||||||
REQUIRE((-_)(40) == -40);
|
REQUIRE((-_)(40) == -40);
|
||||||
|
|||||||
@@ -7,194 +7,15 @@
|
|||||||
#include <kari.hpp/kari.hpp>
|
#include <kari.hpp/kari.hpp>
|
||||||
#include "doctest/doctest.hpp"
|
#include "doctest/doctest.hpp"
|
||||||
|
|
||||||
|
#include "kari_tests.hpp"
|
||||||
|
|
||||||
|
using namespace kari_hpp;
|
||||||
|
using namespace kari_tests;
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
namespace
|
TEST_CASE("kari") {
|
||||||
{
|
|
||||||
const auto _42_tl = []() {
|
|
||||||
return 42;
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto id_tl = [](int v) {
|
|
||||||
return v;
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto minus2_tl = [](int v1, int v2) {
|
|
||||||
return v1 - v2;
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto minus3_tl = [](int v1, int v2, int v3) {
|
|
||||||
return v1 - v2 - v3;
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto minus4_tl = [](int v1, int v2, int v3, int v4) {
|
|
||||||
return v1 - v2 - v3 - v4;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
const auto id_gl = [](auto&& v) {
|
|
||||||
return v;
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto minus2_gl = [](auto&& v1, auto&& v2) {
|
|
||||||
return v1 - v2;
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto minus3_gl = [](auto&& v1, auto&& v2, auto&& v3) {
|
|
||||||
return v1 - v2 - v3;
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto minus4_gl = [](auto&& v1, auto&& v2, auto&& v3, auto&& v4) {
|
|
||||||
return v1 - v2 - v3 - v4;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
struct id_gf {
|
|
||||||
template < typename T >
|
|
||||||
constexpr auto operator()(T&& v) const {
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct minus2_gf {
|
|
||||||
template < typename T1, typename T2 >
|
|
||||||
constexpr auto operator()(T1&& v1, T2&& v2) const {
|
|
||||||
return v1 - v2;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct minus3_gf {
|
|
||||||
template < typename T1, typename T2, typename T3 >
|
|
||||||
constexpr auto operator()(T1&& v1, T2&& v2, T3&& v3) const {
|
|
||||||
return v1 - v2 - v3;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct plusV_gf {
|
|
||||||
template < typename A >
|
|
||||||
constexpr decltype(auto) operator()(A&& a) const {
|
|
||||||
return std::forward<A>(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename A, typename B >
|
|
||||||
constexpr decltype(auto) operator()(A&& a, B&& b) const {
|
|
||||||
return std::forward<A>(a) + std::forward<B>(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename A, typename B, typename... Cs >
|
|
||||||
constexpr decltype(auto) operator()(A&& a, B&& b, Cs&&... cs) const {
|
|
||||||
return (*this)(
|
|
||||||
(*this)(std::forward<A>(a), std::forward<B>(b)),
|
|
||||||
std::forward<Cs>(cs)...);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
struct box {
|
|
||||||
box(int v) : v_(v) {}
|
|
||||||
~box() {
|
|
||||||
v_ = 100500;
|
|
||||||
}
|
|
||||||
|
|
||||||
box(box&& o) : v_(o.v_) {
|
|
||||||
o.v_ = 100500;
|
|
||||||
++moveCount_;
|
|
||||||
}
|
|
||||||
|
|
||||||
box(const box& o) : v_(o.v_) {
|
|
||||||
++copyCount_;
|
|
||||||
}
|
|
||||||
|
|
||||||
box& operator=(box&& o) = delete;
|
|
||||||
box& operator=(const box&) = delete;
|
|
||||||
|
|
||||||
int v() const { return v_; }
|
|
||||||
|
|
||||||
int addV(int add) {
|
|
||||||
v_ += add;
|
|
||||||
return v_;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void resetCounters() {
|
|
||||||
moveCount_ = 0;
|
|
||||||
copyCount_ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int moveCount() {
|
|
||||||
return moveCount_;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int copyCount() {
|
|
||||||
return copyCount_;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
int v_;
|
|
||||||
static int moveCount_;
|
|
||||||
static int copyCount_;
|
|
||||||
};
|
|
||||||
|
|
||||||
int box::moveCount_;
|
|
||||||
int box::copyCount_;
|
|
||||||
|
|
||||||
static box operator+(const box& lhs, const box& rhs) {
|
|
||||||
return box(lhs.v() + rhs.v());
|
|
||||||
}
|
|
||||||
|
|
||||||
static box operator-(const box& lhs, const box& rhs) {
|
|
||||||
return box(lhs.v() - rhs.v());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
struct box_without_move {
|
|
||||||
box_without_move(int v) : v_(v) {}
|
|
||||||
~box_without_move() {
|
|
||||||
v_ = 100500;
|
|
||||||
}
|
|
||||||
|
|
||||||
box_without_move(const box_without_move& o) : v_(o.v_) {
|
|
||||||
++copyCount_;
|
|
||||||
}
|
|
||||||
|
|
||||||
box_without_move& operator=(const box_without_move&) = delete;
|
|
||||||
|
|
||||||
int v() const { return v_; }
|
|
||||||
|
|
||||||
int addV(int add) {
|
|
||||||
v_ += add;
|
|
||||||
return v_;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void resetCounters() {
|
|
||||||
copyCount_ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int copyCount() {
|
|
||||||
return copyCount_;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
int v_;
|
|
||||||
static int copyCount_;
|
|
||||||
};
|
|
||||||
|
|
||||||
int box_without_move::copyCount_;
|
|
||||||
|
|
||||||
static box_without_move operator+(const box_without_move& lhs, const box_without_move& rhs) {
|
|
||||||
return box_without_move(lhs.v() + rhs.v());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
using namespace kari_hpp;
|
|
||||||
|
|
||||||
TEST_CASE("kari_feature") {
|
|
||||||
SUBCASE("ref_functor") {
|
SUBCASE("ref_functor") {
|
||||||
REQUIRE(curry(minus3_gf())(1,2,3) == -4);
|
REQUIRE(curry(minus3_gf())(1,2,3) == -4);
|
||||||
{
|
{
|
||||||
@@ -232,7 +53,7 @@ TEST_CASE("kari_feature") {
|
|||||||
}
|
}
|
||||||
SUBCASE("move_vs_copy") {
|
SUBCASE("move_vs_copy") {
|
||||||
{
|
{
|
||||||
box::resetCounters();
|
box<>::resetCounters();
|
||||||
const auto b1 = box(1);
|
const auto b1 = box(1);
|
||||||
const auto b2 = box(2);
|
const auto b2 = box(2);
|
||||||
const auto b3 = box(3);
|
const auto b3 = box(3);
|
||||||
@@ -241,11 +62,11 @@ TEST_CASE("kari_feature") {
|
|||||||
curry([](auto&& v1, auto&& v2, auto&& v3, auto&& v4, auto&& v5){
|
curry([](auto&& v1, auto&& v2, auto&& v3, auto&& v4, auto&& v5){
|
||||||
return v1 + v2 + v3 + v4 + v5;
|
return v1 + v2 + v3 + v4 + v5;
|
||||||
})(std::move(b1))(std::move(b2))(std::move(b3))(std::move(b4))(std::move(b5));
|
})(std::move(b1))(std::move(b2))(std::move(b3))(std::move(b4))(std::move(b5));
|
||||||
REQUIRE(box::moveCount() == 25);
|
REQUIRE(box<>::moveCount() == 25);
|
||||||
REQUIRE(box::copyCount() == 5);
|
REQUIRE(box<>::copyCount() == 5);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
box::resetCounters();
|
box<>::resetCounters();
|
||||||
auto b1 = box(1);
|
auto b1 = box(1);
|
||||||
auto b2 = box(2);
|
auto b2 = box(2);
|
||||||
auto b3 = box(3);
|
auto b3 = box(3);
|
||||||
@@ -254,35 +75,35 @@ TEST_CASE("kari_feature") {
|
|||||||
curry([](auto&& v1, auto&& v2, auto&& v3, auto&& v4, auto&& v5){
|
curry([](auto&& v1, auto&& v2, auto&& v3, auto&& v4, auto&& v5){
|
||||||
return v1 + v2 + v3 + v4 + v5;
|
return v1 + v2 + v3 + v4 + v5;
|
||||||
})(std::move(b1))(std::move(b2))(std::move(b3))(std::move(b4))(std::move(b5));
|
})(std::move(b1))(std::move(b2))(std::move(b3))(std::move(b4))(std::move(b5));
|
||||||
REQUIRE(box::moveCount() == 30);
|
REQUIRE(box<>::moveCount() == 30);
|
||||||
REQUIRE(box::copyCount() == 0);
|
REQUIRE(box<>::copyCount() == 0);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
box::resetCounters();
|
box<>::resetCounters();
|
||||||
curry([](auto&& v1, auto&& v2, auto&& v3, auto&& v4, auto&& v5){
|
curry([](auto&& v1, auto&& v2, auto&& v3, auto&& v4, auto&& v5){
|
||||||
return v1 + v2 + v3 + v4 + v5;
|
return v1 + v2 + v3 + v4 + v5;
|
||||||
})(box(1))(box(2))(box(3))(box(4))(box(5));
|
})(box(1))(box(2))(box(3))(box(4))(box(5));
|
||||||
REQUIRE(box::moveCount() == 30);
|
REQUIRE(box<>::moveCount() == 30);
|
||||||
REQUIRE(box::copyCount() == 0);
|
REQUIRE(box<>::copyCount() == 0);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
box::resetCounters();
|
box<>::resetCounters();
|
||||||
curry([](auto&& v1, auto&& v2, auto&& v3, auto&& v4, auto&& v5){
|
curry([](auto&& v1, auto&& v2, auto&& v3, auto&& v4, auto&& v5){
|
||||||
return v1 + v2 + v3 + v4 + v5;
|
return v1 + v2 + v3 + v4 + v5;
|
||||||
})(box(1),box(2))(box(3),box(4))(box(5));
|
})(box(1),box(2))(box(3),box(4))(box(5));
|
||||||
REQUIRE(box::moveCount() == 30);
|
REQUIRE(box<>::moveCount() == 30);
|
||||||
REQUIRE(box::copyCount() == 0);
|
REQUIRE(box<>::copyCount() == 0);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
box::resetCounters();
|
box<>::resetCounters();
|
||||||
curry([](auto&& v1, auto&& v2, auto&& v3, auto&& v4, auto&& v5){
|
curry([](auto&& v1, auto&& v2, auto&& v3, auto&& v4, auto&& v5){
|
||||||
return v1 + v2 + v3 + v4 + v5;
|
return v1 + v2 + v3 + v4 + v5;
|
||||||
})(box(1),box(2),box(3),box(4),box(5));
|
})(box(1),box(2),box(3),box(4),box(5));
|
||||||
REQUIRE(box::moveCount() == 30);
|
REQUIRE(box<>::moveCount() == 30);
|
||||||
REQUIRE(box::copyCount() == 0);
|
REQUIRE(box<>::copyCount() == 0);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
box::resetCounters();
|
box<>::resetCounters();
|
||||||
const auto c0 = curry([](auto&& v1, auto&& v2, auto&& v3, auto&& v4, auto&& v5){
|
const auto c0 = curry([](auto&& v1, auto&& v2, auto&& v3, auto&& v4, auto&& v5){
|
||||||
return v1 + v2 + v3 + v4 + v5;
|
return v1 + v2 + v3 + v4 + v5;
|
||||||
});
|
});
|
||||||
@@ -292,11 +113,11 @@ TEST_CASE("kari_feature") {
|
|||||||
const auto c4 = c3(box(4));
|
const auto c4 = c3(box(4));
|
||||||
const auto c5 = c4(box(5));
|
const auto c5 = c4(box(5));
|
||||||
REQUIRE(c5.v() == 15);
|
REQUIRE(c5.v() == 15);
|
||||||
REQUIRE(box::moveCount() == 30);
|
REQUIRE(box<>::moveCount() == 30);
|
||||||
REQUIRE(box::copyCount() == 10);
|
REQUIRE(box<>::copyCount() == 10);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
box_without_move::resetCounters();
|
box_without_move<>::resetCounters();
|
||||||
const auto c0 = curry([](auto&& v1, auto&& v2, auto&& v3, auto&& v4, auto&& v5){
|
const auto c0 = curry([](auto&& v1, auto&& v2, auto&& v3, auto&& v4, auto&& v5){
|
||||||
return v1 + v2 + v3 + v4 + v5;
|
return v1 + v2 + v3 + v4 + v5;
|
||||||
});
|
});
|
||||||
@@ -306,16 +127,16 @@ TEST_CASE("kari_feature") {
|
|||||||
const auto c4 = c3(box_without_move(4));
|
const auto c4 = c3(box_without_move(4));
|
||||||
const auto c5 = c4(box_without_move(5));
|
const auto c5 = c4(box_without_move(5));
|
||||||
REQUIRE(c5.v() == 15);
|
REQUIRE(c5.v() == 15);
|
||||||
REQUIRE(box_without_move::copyCount() == 40);
|
REQUIRE(box_without_move<>::copyCount() == 40);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
box::resetCounters();
|
box<>::resetCounters();
|
||||||
curryV(plusV_gf())(box(1),box(2),box(3),box(4),box(5))();
|
curryV(plusV_gf())(box(1),box(2),box(3),box(4),box(5))();
|
||||||
REQUIRE(box::moveCount() == 35);
|
REQUIRE(box<>::moveCount() == 35);
|
||||||
REQUIRE(box::copyCount() == 0);
|
REQUIRE(box<>::copyCount() == 0);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
box::resetCounters();
|
box<>::resetCounters();
|
||||||
const auto c0 = curryV(plusV_gf());
|
const auto c0 = curryV(plusV_gf());
|
||||||
const auto c1 = c0(box(1));
|
const auto c1 = c0(box(1));
|
||||||
const auto c2 = c1(box(2));
|
const auto c2 = c1(box(2));
|
||||||
@@ -323,8 +144,8 @@ TEST_CASE("kari_feature") {
|
|||||||
const auto c4 = c3(box(4));
|
const auto c4 = c3(box(4));
|
||||||
const auto c5 = c4(box(5));
|
const auto c5 = c4(box(5));
|
||||||
REQUIRE(c5().v() == 15);
|
REQUIRE(c5().v() == 15);
|
||||||
REQUIRE(box::moveCount() == 35);
|
REQUIRE(box<>::moveCount() == 35);
|
||||||
REQUIRE(box::copyCount() == 15);
|
REQUIRE(box<>::copyCount() == 15);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SUBCASE("persistent") {
|
SUBCASE("persistent") {
|
||||||
@@ -352,7 +173,7 @@ TEST_CASE("kari_feature") {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("kari") {
|
TEST_CASE("kari/curry") {
|
||||||
SUBCASE("arity/min_arity") {
|
SUBCASE("arity/min_arity") {
|
||||||
REQUIRE(curry(minus3_gl).min_arity() == 0);
|
REQUIRE(curry(minus3_gl).min_arity() == 0);
|
||||||
REQUIRE(curryV(plusV_gf()).min_arity() == std::numeric_limits<std::size_t>::max());
|
REQUIRE(curryV(plusV_gf()).min_arity() == std::numeric_limits<std::size_t>::max());
|
||||||
@@ -549,14 +370,14 @@ TEST_CASE("kari") {
|
|||||||
}
|
}
|
||||||
SUBCASE("member_functions") {
|
SUBCASE("member_functions") {
|
||||||
{
|
{
|
||||||
auto c0 = curry(&box::addV);
|
auto c0 = curry(&box<>::addV);
|
||||||
auto c1 = curry(&box::v);
|
auto c1 = curry(&box<>::v);
|
||||||
REQUIRE(c0(box(10), 2) == 12);
|
REQUIRE(c0(box(10), 2) == 12);
|
||||||
REQUIRE(c1(box(12)) == 12);
|
REQUIRE(c1(box(12)) == 12);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto c0 = curry(&box::addV);
|
auto c0 = curry(&box<>::addV);
|
||||||
auto c1 = curry(&box::v);
|
auto c1 = curry(&box<>::v);
|
||||||
|
|
||||||
auto b1 = box(10);
|
auto b1 = box(10);
|
||||||
const auto b2 = box(10);
|
const auto b2 = box(10);
|
||||||
@@ -572,7 +393,7 @@ TEST_CASE("kari") {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
SUBCASE("member_objects") {
|
SUBCASE("member_objects") {
|
||||||
struct box2 : box {
|
struct box2 : box<> {
|
||||||
box2(int v) : box(v), ov(v) {}
|
box2(int v) : box(v), ov(v) {}
|
||||||
int ov;
|
int ov;
|
||||||
};
|
};
|
||||||
|
|||||||
195
untests/kari_tests.hpp
Normal file
195
untests/kari_tests.hpp
Normal file
@@ -0,0 +1,195 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* This file is part of the "https://github.com/BlackMATov/kari.hpp"
|
||||||
|
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||||
|
* Copyright (C) 2017-2020, by Matvey Cherevko (blackmatov@gmail.com)
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace kari_tests
|
||||||
|
{
|
||||||
|
inline constexpr auto _42_tl = []() {
|
||||||
|
return 42;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline constexpr auto id_tl = [](int v) {
|
||||||
|
return v;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline constexpr auto minus2_tl = [](int v1, int v2) {
|
||||||
|
return v1 - v2;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline constexpr auto minus3_tl = [](int v1, int v2, int v3) {
|
||||||
|
return v1 - v2 - v3;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline constexpr auto minus4_tl = [](int v1, int v2, int v3, int v4) {
|
||||||
|
return v1 - v2 - v3 - v4;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline constexpr auto id_gl = [](auto&& v) {
|
||||||
|
return v;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline constexpr auto minus2_gl = [](auto&& v1, auto&& v2) {
|
||||||
|
return v1 - v2;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline constexpr auto minus3_gl = [](auto&& v1, auto&& v2, auto&& v3) {
|
||||||
|
return v1 - v2 - v3;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline constexpr auto minus4_gl = [](auto&& v1, auto&& v2, auto&& v3, auto&& v4) {
|
||||||
|
return v1 - v2 - v3 - v4;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace kari_tests
|
||||||
|
{
|
||||||
|
struct id_gf {
|
||||||
|
template < typename T >
|
||||||
|
constexpr auto operator()(T&& v) const {
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct minus2_gf {
|
||||||
|
template < typename T1, typename T2 >
|
||||||
|
constexpr auto operator()(T1&& v1, T2&& v2) const {
|
||||||
|
return v1 - v2;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct minus3_gf {
|
||||||
|
template < typename T1, typename T2, typename T3 >
|
||||||
|
constexpr auto operator()(T1&& v1, T2&& v2, T3&& v3) const {
|
||||||
|
return v1 - v2 - v3;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct plusV_gf {
|
||||||
|
template < typename A >
|
||||||
|
constexpr decltype(auto) operator()(A&& a) const {
|
||||||
|
return std::forward<A>(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename A, typename B >
|
||||||
|
constexpr decltype(auto) operator()(A&& a, B&& b) const {
|
||||||
|
return std::forward<A>(a) + std::forward<B>(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename A, typename B, typename... Cs >
|
||||||
|
constexpr decltype(auto) operator()(A&& a, B&& b, Cs&&... cs) const {
|
||||||
|
return (*this)(
|
||||||
|
(*this)(std::forward<A>(a), std::forward<B>(b)),
|
||||||
|
std::forward<Cs>(cs)...);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace kari_tests
|
||||||
|
{
|
||||||
|
template < typename = void >
|
||||||
|
struct box {
|
||||||
|
box(int v) : v_(v) {}
|
||||||
|
~box() {
|
||||||
|
v_ = 100500;
|
||||||
|
}
|
||||||
|
|
||||||
|
box(box&& o) : v_(o.v_) {
|
||||||
|
o.v_ = 100500;
|
||||||
|
++moveCount_;
|
||||||
|
}
|
||||||
|
|
||||||
|
box(const box& o) : v_(o.v_) {
|
||||||
|
++copyCount_;
|
||||||
|
}
|
||||||
|
|
||||||
|
box& operator=(box&& o) = delete;
|
||||||
|
box& operator=(const box&) = delete;
|
||||||
|
|
||||||
|
int v() const { return v_; }
|
||||||
|
|
||||||
|
int addV(int add) {
|
||||||
|
v_ += add;
|
||||||
|
return v_;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void resetCounters() {
|
||||||
|
moveCount_ = 0;
|
||||||
|
copyCount_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int moveCount() {
|
||||||
|
return moveCount_;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int copyCount() {
|
||||||
|
return copyCount_;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
int v_;
|
||||||
|
static int moveCount_;
|
||||||
|
static int copyCount_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
int box<T>::moveCount_;
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
int box<T>::copyCount_;
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
inline box<T> operator+(const box<T>& lhs, const box<T>& rhs) {
|
||||||
|
return box(lhs.v() + rhs.v());
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
inline box<T> operator-(const box<T>& lhs, const box<T>& rhs) {
|
||||||
|
return box(lhs.v() - rhs.v());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace kari_tests
|
||||||
|
{
|
||||||
|
template < typename = void >
|
||||||
|
struct box_without_move {
|
||||||
|
box_without_move(int v) : v_(v) {}
|
||||||
|
~box_without_move() {
|
||||||
|
v_ = 100500;
|
||||||
|
}
|
||||||
|
|
||||||
|
box_without_move(const box_without_move& o) : v_(o.v_) {
|
||||||
|
++copyCount_;
|
||||||
|
}
|
||||||
|
|
||||||
|
box_without_move& operator=(const box_without_move&) = delete;
|
||||||
|
|
||||||
|
int v() const { return v_; }
|
||||||
|
|
||||||
|
int addV(int add) {
|
||||||
|
v_ += add;
|
||||||
|
return v_;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void resetCounters() {
|
||||||
|
copyCount_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int copyCount() {
|
||||||
|
return copyCount_;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
int v_;
|
||||||
|
static int copyCount_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
int box_without_move<T>::copyCount_;
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
inline box_without_move<T> operator+(const box_without_move<T>& lhs, const box_without_move<T>& rhs) {
|
||||||
|
return box_without_move(lhs.v() + rhs.v());
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user