blob: f24b88cf4047f945afa94699f698f7fbdaea7939 [file] [log] [blame]
/**
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <functional>
#include <string>
#include <type_traits>
#include "../TestBase.h"
#include "utils/GeneralUtils.h"
namespace utils = org::apache::nifi::minifi::utils;
static_assert(std::is_same<decltype(utils::make_unique<char16_t>()), std::unique_ptr<char16_t>>::value, "utils::make_unique type must be correct");
TEST_CASE("GeneralUtils::make_unique", "[make_unique]") {
const auto pstr = utils::make_unique<std::string>("test string");
REQUIRE("test string" == *pstr);
}
// intdiv_ceil
static_assert(0 == utils::intdiv_ceil(0, 1), "");
static_assert(0 == utils::intdiv_ceil(0, 2), "");
static_assert(1 == utils::intdiv_ceil(1, 2), "");
static_assert(1 == utils::intdiv_ceil(1, 3), "");
static_assert(1 == utils::intdiv_ceil(3, 3), "");
static_assert(2 == utils::intdiv_ceil(4, 3), "");
static_assert(2 == utils::intdiv_ceil(5, 3), "");
static_assert(0 == utils::intdiv_ceil(-1, 3), "");
static_assert(-1 == utils::intdiv_ceil(-3, 3), "");
static_assert(-1 == utils::intdiv_ceil(-4, 3), "");
static_assert(2 == utils::intdiv_ceil(-4, -3), "");
static_assert(2 == utils::intdiv_ceil(-5, -3), "");
static_assert(0 == utils::intdiv_ceil(1, -3), "");
static_assert(-1 == utils::intdiv_ceil(5, -3), "");
static_assert(3 == utils::intdiv_ceil(6, 2), "");
static_assert(-3 == utils::intdiv_ceil(-6, 2), "");
static_assert(-3 == utils::intdiv_ceil(6, -2), "");
static_assert(3 == utils::intdiv_ceil(-6, -2), "");
static_assert(0 == utils::intdiv_ceil(0, -10), "");
template<int N, int D, typename = void>
struct does_compile : std::false_type {};
template<int N, int D>
struct does_compile<N, D,
// we must force evaluation so decltype won't do
typename std::enable_if<(utils::intdiv_ceil(N, D), true)>::type> : std::true_type {};
static_assert(does_compile<2, 3>::value, "does_compile should work");
static_assert(!does_compile<1, 0>::value, "constexpr division by zero shouldn't compile");
TEST_CASE("GeneralUtils::exchange", "[exchange]") {
int a = 1;
int b = 2;
a = utils::exchange(b, 0);
REQUIRE(2 == a);
REQUIRE(0 == b);
}
static_assert(std::is_same<decltype(utils::void_t<char16_t>()), void>::value, "utils::void_t single arg must work");
static_assert(std::is_same<decltype(utils::void_t<int, double, bool, void, char16_t>()), void>::value, "utils::void_t multi arg must work");
TEST_CASE("GeneralUtils::invoke pointer to member function", "[invoke memfnptr]") {
const int result{0xc1ca};
struct Tester {
bool called{};
int memfn(const int arg) {
REQUIRE(42 == arg);
called = true;
return result;
}
};
// normal
REQUIRE(result == utils::invoke(&Tester::memfn, Tester{}, 42));
// reference_wrapper
Tester t2;
const auto ref_wrapper = std::ref(t2);
REQUIRE(result == utils::invoke(&Tester::memfn, ref_wrapper, 42));
REQUIRE(t2.called);
// pointer
Tester t3;
REQUIRE(result == utils::invoke(&Tester::memfn, &t3, 42));
REQUIRE(t3.called);
}
TEST_CASE("GeneralUtils::invoke pointer to data member", "[invoke data member]") {
struct Times2 {
int value;
explicit Times2(const int i) :value{i * 2} {}
};
// normal
REQUIRE(24 == utils::invoke(&Times2::value, Times2{12}));
// reference_wrapper
Times2 t2{42};
const auto ref_wrapper = std::ref(t2);
REQUIRE(84 == utils::invoke(&Times2::value, ref_wrapper));
// pointer
Times2 t3{0};
REQUIRE(0 == utils::invoke(&Times2::value, &t3));
}
namespace {
bool free_function(const bool b) { return b; }
} // namespace
TEST_CASE("GeneralUtils::invoke FunctionObject", "[invoke function object]") {
REQUIRE(true == utils::invoke(&free_function, true));
REQUIRE(false == utils::invoke(&free_function, false));
const auto n = 3;
const auto int_timesn = [n](const int i) { return n * i; };
// lambda with capture
REQUIRE(60 == utils::invoke(int_timesn, 20));
}