Commit efae0076 authored by Marco Bubke's avatar Marco Bubke

Add fold expression

parent ff9239d4
......@@ -3,4 +3,5 @@ TEMPLATE = subdirs
SUBDIRS = \
polymorphism \
sorting \
exceptions
exceptions \
fold-expression
#include <googletest.h>
#include <QByteArray>
#include <cstring>
#include <numeric>
#include <string>
#include <type_traits>
using testing::ElementsAre;
using testing::Eq;
using testing::StrEq;
template <typename Type>
constexpr auto sum(Type value1, Type value2) {
return value1 + value2;
}
template <typename Type, typename... Types>
constexpr auto sum(Type value, Types&&... values) {
return sum(value, sum(values...));
}
TEST(FoldExpression, SumRecursive)
{
auto value = sum(1, 2, 3, 4, 5, 6);
ASSERT_THAT(value, Eq(21));
}
template <typename... Types>
constexpr auto sum2(Types&&... values) {
return (0 + ... + values);
}
TEST(FoldExpression, Sum)
{
auto value = sum2(1, 2, 3, 4, 5, 6);
ASSERT_THAT(value, Eq(21));
}
namespace Detail {
template <typename Type>
struct MaxWrapper {
const Type &value;
};
template <typename T, typename U, typename ResultType=std::common_type_t<T,U>>
constexpr MaxWrapper<ResultType> operator%(const MaxWrapper<T> &first, const MaxWrapper<U> &second)
{
return MaxWrapper<ResultType>{std::max(first.value, second.value)};
}
} //namespace detail
template <typename... Types>
constexpr auto max(Types&&... values) {
return (Detail::MaxWrapper<Types>{values} % ...).value;
}
TEST(FoldExpression, MaximumValue)
{
auto maximumValue = max(1, 2, 12345, 4, 5, 6, 34, 3434);
ASSERT_THAT(maximumValue, Eq(12345));
}
template <typename Type>
constexpr auto max2(Type value) {
return value;
}
template <typename Type, typename... Types>
constexpr auto max2(Type value, Types&&... values) {
return std::max(value, max2(values...));
}
TEST(FoldExpression, MaximumValueRecursive)
{
auto maximumValue = max2(1, 2, 12345, 4, 5, 6, 34, 3434);
ASSERT_THAT(maximumValue, Eq(12345));
}
template <typename Type>
std::size_t string_size(Type&& container)
{
return std::size(container);
}
std::size_t string_size(const char *string)
{
return std::strlen(string);
}
template <typename... Types>
std::size_t sum_size(Types&&... container)
{
return (string_size(container) + ... + 0);
}
template <typename ResultType,
typename Type>
void appendString(ResultType& result, Type&& string)
{
result.insert(result.end(), std::begin(string), std::end(string));
}
template <typename ResultType>
void appendString(ResultType& result, const char *string)
{
result.insert(result.end(), string, string + std::strlen(string));
}
template <typename Type>
void appendString(QByteArray& result, Type&& string)
{
result.append(string.data(), string.size());
}
void appendString(QByteArray& result, const char *string)
{
result.append(string, strlen(string));
}
template <typename ResultType = std::string,
typename... Types>
ResultType string_concat(Types&&... strings)
{
ResultType result;
result.reserve(sum_size(strings...));
(appendString(result, strings), ...);
return result;
}
TEST(FoldExpression, StringConcatination)
{
auto text = string_concat("foo", std::string("bar"), "poo", QByteArray("tee"));
ASSERT_THAT(text, Eq("foobarpootee"));
}
TEST(FoldExpression, StringConcatinationStdVector)
{
auto text = string_concat<std::vector<char>>("foo", std::string("bar"), "poo", QByteArray("tee"));
ASSERT_THAT(text.data(), StrEq("foobarpootee"));
}
TEST(FoldExpression, StringConcatinationQByteArray)
{
auto text = string_concat<QByteArray>("foo", std::string("bar"), "poo", QByteArray("tee"));
ASSERT_THAT(text, Eq("foobarpootee"));
}
include(../shared/test.pri)
TARGET = foldexpression
SOURCES += \
fold-expression-test.cpp
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment