first commit

This commit is contained in:
stuce-bot 2025-06-30 20:47:33 +02:00
commit 5893b00dd2
1669 changed files with 1982740 additions and 0 deletions

View file

@ -0,0 +1,72 @@
#include <gtest/gtest.h>
#include <m5_utility/stl/optional.hpp>
TEST(Optional, Assignment)
{
m5::stl::optional<int> o1 = 42;
m5::stl::optional<int> o2 = 12;
m5::stl::optional<int> o3;
o1 = o1;
EXPECT_TRUE(*o1 == 42);
o1 = o2;
EXPECT_TRUE(*o1 == 12);
o1 = o3;
EXPECT_TRUE(!o1);
o1 = 42;
EXPECT_TRUE(*o1 == 42);
o1 = m5::stl::nullopt;
EXPECT_TRUE(!o1);
o1 = std::move(o2);
EXPECT_TRUE(*o1 == 12);
m5::stl::optional<short> o4 = 42;
o1 = o4;
EXPECT_TRUE(*o1 == 42);
o1 = std::move(o4);
EXPECT_TRUE(*o1 == 42);
}
TEST(Optional, AssignmentReference)
{
auto i = 42;
auto j = 12;
m5::stl::optional<int&> o1 = i;
m5::stl::optional<int&> o2 = j;
m5::stl::optional<int&> o3;
o1 = o1;
EXPECT_TRUE(*o1 == 42);
EXPECT_TRUE(&*o1 == &i);
o1 = o2;
EXPECT_TRUE(*o1 == 12);
o1 = o3;
EXPECT_TRUE(!o1);
auto k = 42;
o1 = k;
EXPECT_TRUE(*o1 == 42);
EXPECT_TRUE(*o1 == i);
EXPECT_TRUE(*o1 == k);
EXPECT_TRUE(&*o1 != &i);
EXPECT_TRUE(&*o1 == &k);
k = 12;
EXPECT_TRUE(*o1 == 12);
o1 = m5::stl::nullopt;
EXPECT_TRUE(!o1);
o1 = std::move(o2);
EXPECT_TRUE(*o1 == 12);
}

View file

@ -0,0 +1,136 @@
#include <gtest/gtest.h>
#include <m5_utility/stl/optional.hpp>
// Old versions of GCC don't have the correct trait names. Could fix them up if needs be.
#if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9 && !defined(__clang__))
// nothing for now
#else
TEST(Optional, Triviality)
{
EXPECT_TRUE(std::is_trivially_copy_constructible<m5::stl::optional<int> >::value);
EXPECT_TRUE(std::is_trivially_copy_assignable<m5::stl::optional<int> >::value);
EXPECT_TRUE(std::is_trivially_move_constructible<m5::stl::optional<int> >::value);
EXPECT_TRUE(std::is_trivially_move_assignable<m5::stl::optional<int> >::value);
EXPECT_TRUE(std::is_trivially_destructible<m5::stl::optional<int> >::value);
{
struct T {
T(const T&) = default;
T(T&&) = default;
T& operator=(const T&) = default;
T& operator=(T&&) = default;
~T() = default;
};
EXPECT_TRUE(std::is_trivially_copy_constructible<m5::stl::optional<T> >::value);
EXPECT_TRUE(std::is_trivially_copy_assignable<m5::stl::optional<T> >::value);
EXPECT_TRUE(std::is_trivially_move_constructible<m5::stl::optional<T> >::value);
EXPECT_TRUE(std::is_trivially_move_assignable<m5::stl::optional<T> >::value);
EXPECT_TRUE(std::is_trivially_destructible<m5::stl::optional<T> >::value);
}
{
struct T {
T(const T&)
{
}
T(T&&)
{
}
T& operator=(const T&)
{
return *this;
}
T& operator=(T&&)
{
return *this;
};
~T()
{
}
};
EXPECT_TRUE(!std::is_trivially_copy_constructible<m5::stl::optional<T> >::value);
EXPECT_TRUE(!std::is_trivially_copy_assignable<m5::stl::optional<T> >::value);
EXPECT_TRUE(!std::is_trivially_move_constructible<m5::stl::optional<T> >::value);
EXPECT_TRUE(!std::is_trivially_move_assignable<m5::stl::optional<T> >::value);
EXPECT_TRUE(!std::is_trivially_destructible<m5::stl::optional<T> >::value);
}
}
TEST(Optional, Deletion)
{
EXPECT_TRUE(std::is_copy_constructible<m5::stl::optional<int> >::value);
EXPECT_TRUE(std::is_copy_assignable<m5::stl::optional<int> >::value);
EXPECT_TRUE(std::is_move_constructible<m5::stl::optional<int> >::value);
EXPECT_TRUE(std::is_move_assignable<m5::stl::optional<int> >::value);
EXPECT_TRUE(std::is_destructible<m5::stl::optional<int> >::value);
{
struct T {
T(const T&) = default;
T(T&&) = default;
T& operator=(const T&) = default;
T& operator=(T&&) = default;
~T() = default;
};
EXPECT_TRUE(std::is_copy_constructible<m5::stl::optional<T> >::value);
EXPECT_TRUE(std::is_copy_assignable<m5::stl::optional<T> >::value);
EXPECT_TRUE(std::is_move_constructible<m5::stl::optional<T> >::value);
EXPECT_TRUE(std::is_move_assignable<m5::stl::optional<T> >::value);
EXPECT_TRUE(std::is_destructible<m5::stl::optional<T> >::value);
}
{
struct T {
T(const T&) = delete;
T(T&&) = delete;
T& operator=(const T&) = delete;
T& operator=(T&&) = delete;
};
EXPECT_TRUE(!std::is_copy_constructible<m5::stl::optional<T> >::value);
EXPECT_TRUE(!std::is_copy_assignable<m5::stl::optional<T> >::value);
EXPECT_TRUE(!std::is_move_constructible<m5::stl::optional<T> >::value);
EXPECT_TRUE(!std::is_move_assignable<m5::stl::optional<T> >::value);
}
{
struct T {
T(const T&) = delete;
T(T&&) = default;
T& operator=(const T&) = delete;
T& operator=(T&&) = default;
};
EXPECT_TRUE(!std::is_copy_constructible<m5::stl::optional<T> >::value);
EXPECT_TRUE(!std::is_copy_assignable<m5::stl::optional<T> >::value);
EXPECT_TRUE(std::is_move_constructible<m5::stl::optional<T> >::value);
EXPECT_TRUE(std::is_move_assignable<m5::stl::optional<T> >::value);
}
{
struct T {
T(const T&) = default;
T(T&&) = delete;
T& operator=(const T&) = default;
T& operator=(T&&) = delete;
};
EXPECT_TRUE(std::is_copy_constructible<m5::stl::optional<T> >::value);
EXPECT_TRUE(std::is_copy_assignable<m5::stl::optional<T> >::value);
}
}
#endif

View file

@ -0,0 +1,44 @@
#include <gtest/gtest.h>
#include <m5_utility/stl/optional.hpp>
#include "helper.hpp"
TEST(Optional, Constexpr)
{
#if !defined(TL_OPTIONAL_MSVC2015) && defined(TL_OPTIONAL_CXX14)
{
SCOPED_TRACE("empty construct");
constexpr m5::stl::optional<int> o2{};
constexpr m5::stl::optional<int> o3 = {};
constexpr m5::stl::optional<int> o4 = m5::stl::nullopt;
constexpr m5::stl::optional<int> o5 = {m5::stl::nullopt};
constexpr m5::stl::optional<int> o6(m5::stl::nullopt);
STATIC_EXPECT_TRUE(!o2);
STATIC_EXPECT_TRUE(!o3);
STATIC_EXPECT_TRUE(!o4);
STATIC_EXPECT_TRUE(!o5);
STATIC_EXPECT_TRUE(!o6);
}
{
SCOPED_TRACE("value construct");
constexpr m5::stl::optional<int> o1 = 42;
constexpr m5::stl::optional<int> o2{42};
constexpr m5::stl::optional<int> o3(42);
constexpr m5::stl::optional<int> o4 = {42};
constexpr int i = 42;
constexpr m5::stl::optional<int> o5 = std::move(i);
constexpr m5::stl::optional<int> o6{std::move(i)};
constexpr m5::stl::optional<int> o7(std::move(i));
constexpr m5::stl::optional<int> o8 = {std::move(i)};
STATIC_EXPECT_TRUE(*o1 == 42);
STATIC_EXPECT_TRUE(*o2 == 42);
STATIC_EXPECT_TRUE(*o3 == 42);
STATIC_EXPECT_TRUE(*o4 == 42);
STATIC_EXPECT_TRUE(*o5 == 42);
STATIC_EXPECT_TRUE(*o6 == 42);
STATIC_EXPECT_TRUE(*o7 == 42);
STATIC_EXPECT_TRUE(*o8 == 42);
}
#endif
}

View file

@ -0,0 +1,69 @@
#include <gtest/gtest.h>
#include <m5_utility/stl/optional.hpp>
#include <vector>
namespace constructor {
struct foo {
foo() = default;
foo(foo &) = delete;
foo(foo &&) noexcept
{
}
};
} // namespace constructor
TEST(Optional, Constructors)
{
m5::stl::optional<int> o1;
EXPECT_TRUE(!o1);
m5::stl::optional<int> o2 = m5::stl::nullopt;
EXPECT_TRUE(!o2);
m5::stl::optional<int> o3 = 42;
EXPECT_TRUE(*o3 == 42);
m5::stl::optional<int> o4 = o3;
EXPECT_TRUE(*o4 == 42);
m5::stl::optional<int> o5 = o1;
EXPECT_TRUE(!o5);
m5::stl::optional<int> o6 = std::move(o3);
EXPECT_TRUE(*o6 == 42);
m5::stl::optional<short> o7 = 42;
EXPECT_TRUE(*o7 == 42);
m5::stl::optional<int> o8 = o7;
EXPECT_TRUE(*o8 == 42);
m5::stl::optional<int> o9 = std::move(o7);
EXPECT_TRUE(*o9 == 42);
{
m5::stl::optional<int &> o;
EXPECT_TRUE(!o);
m5::stl::optional<int &> oo = o;
EXPECT_TRUE(!oo);
}
{
auto i = 42;
m5::stl::optional<int &> o = i;
EXPECT_TRUE(o);
EXPECT_TRUE(*o == 42);
m5::stl::optional<int &> oo = o;
EXPECT_TRUE(oo);
EXPECT_TRUE(*oo == 42);
}
std::vector<constructor::foo> v;
v.emplace_back();
m5::stl::optional<std::vector<constructor::foo>> ov = std::move(v);
EXPECT_TRUE(ov->size() == 1);
}

View file

@ -0,0 +1,27 @@
#include <gtest/gtest.h>
#include <m5_utility/stl/optional.hpp>
#include <utility>
#include <tuple>
TEST(Optional, Emplace)
{
m5::stl::optional<std::pair<std::pair<int, int>, std::pair<double, double>>> i;
i.emplace(std::piecewise_construct, std::make_tuple(0, 2), std::make_tuple(3, 4));
EXPECT_TRUE(i->first.first == 0);
EXPECT_TRUE(i->first.second == 2);
EXPECT_TRUE(i->second.first == 3);
EXPECT_TRUE(i->second.second == 4);
}
struct A {
A()
{
throw std::exception();
}
};
TEST(Optional, EmplaceWithException)
{
m5::stl::optional<A> a;
EXPECT_ANY_THROW(a.emplace());
}

View file

@ -0,0 +1,501 @@
#include <gtest/gtest.h>
#include <m5_utility/stl/optional.hpp>
#include <string>
#include "helper.hpp"
constexpr int get_int(int)
{
return 42;
}
TL_OPTIONAL_11_CONSTEXPR m5::stl::optional<int> get_opt_int(int)
{
return 42;
}
// What is Clang Format up to?!
TEST(Optional, Monadic)
{
{ // lhs is empty
SCOPED_TRACE("map");
m5::stl::optional<int> o1;
auto o1r = o1.map([](int i) { return i + 2; });
STATIC_EXPECT_TRUE((std::is_same<decltype(o1r), m5::stl::optional<int>>::value));
EXPECT_TRUE(!o1r);
// lhs has value
m5::stl::optional<int> o2 = 40;
auto o2r = o2.map([](int i) { return i + 2; });
STATIC_EXPECT_TRUE((std::is_same<decltype(o2r), m5::stl::optional<int>>::value));
EXPECT_TRUE(o2r.value() == 42);
struct rval_call_map {
double operator()(int) &&
{
return 42.0;
};
};
// ensure that function object is forwarded
m5::stl::optional<int> o3 = 42;
auto o3r = o3.map(rval_call_map{});
STATIC_EXPECT_TRUE((std::is_same<decltype(o3r), m5::stl::optional<double>>::value));
EXPECT_TRUE(o3r.value() == 42);
// ensure that lhs is forwarded
m5::stl::optional<int> o4 = 40;
auto o4r = std::move(o4).map([](int &&i) { return i + 2; });
STATIC_EXPECT_TRUE((std::is_same<decltype(o4r), m5::stl::optional<int>>::value));
EXPECT_TRUE(o4r.value() == 42);
// ensure that lhs is const-propagated
const m5::stl::optional<int> o5 = 40;
auto o5r = o5.map([](const int &i) { return i + 2; });
STATIC_EXPECT_TRUE((std::is_same<decltype(o5r), m5::stl::optional<int>>::value));
EXPECT_TRUE(o5r.value() == 42);
// test void return
m5::stl::optional<int> o7 = 40;
auto f7 = [](const int &) { return; };
auto o7r = o7.map(f7);
STATIC_EXPECT_TRUE((std::is_same<decltype(o7r), m5::stl::optional<m5::stl::monostate>>::value));
EXPECT_TRUE(o7r.has_value());
// test each overload in turn
m5::stl::optional<int> o8 = 42;
auto o8r = o8.map([](int) { return 42; });
EXPECT_TRUE(*o8r == 42);
m5::stl::optional<int> o9 = 42;
auto o9r = o9.map([](int) { return; });
EXPECT_TRUE(o9r);
m5::stl::optional<int> o12 = 42;
auto o12r = std::move(o12).map([](int) { return 42; });
EXPECT_TRUE(*o12r == 42);
m5::stl::optional<int> o13 = 42;
auto o13r = std::move(o13).map([](int) { return; });
EXPECT_TRUE(o13r);
const m5::stl::optional<int> o16 = 42;
auto o16r = o16.map([](int) { return 42; });
EXPECT_TRUE(*o16r == 42);
const m5::stl::optional<int> o17 = 42;
auto o17r = o17.map([](int) { return; });
EXPECT_TRUE(o17r);
const m5::stl::optional<int> o20 = 42;
auto o20r = std::move(o20).map([](int) { return 42; });
EXPECT_TRUE(*o20r == 42);
const m5::stl::optional<int> o21 = 42;
auto o21r = std::move(o21).map([](int) { return; });
EXPECT_TRUE(o21r);
m5::stl::optional<int> o24 = m5::stl::nullopt;
auto o24r = o24.map([](int) { return 42; });
EXPECT_TRUE(!o24r);
m5::stl::optional<int> o25 = m5::stl::nullopt;
auto o25r = o25.map([](int) { return; });
EXPECT_TRUE(!o25r);
m5::stl::optional<int> o28 = m5::stl::nullopt;
auto o28r = std::move(o28).map([](int) { return 42; });
EXPECT_TRUE(!o28r);
m5::stl::optional<int> o29 = m5::stl::nullopt;
auto o29r = std::move(o29).map([](int) { return; });
EXPECT_TRUE(!o29r);
const m5::stl::optional<int> o32 = m5::stl::nullopt;
auto o32r = o32.map([](int) { return 42; });
EXPECT_TRUE(!o32r);
const m5::stl::optional<int> o33 = m5::stl::nullopt;
auto o33r = o33.map([](int) { return; });
EXPECT_TRUE(!o33r);
const m5::stl::optional<int> o36 = m5::stl::nullopt;
auto o36r = std::move(o36).map([](int) { return 42; });
EXPECT_TRUE(!o36r);
const m5::stl::optional<int> o37 = m5::stl::nullopt;
auto o37r = std::move(o37).map([](int) { return; });
EXPECT_TRUE(!o37r);
// callable which returns a reference
m5::stl::optional<int> o38 = 42;
auto o38r = o38.map([](int &i) -> const int &{ return i; });
EXPECT_TRUE(o38r);
EXPECT_TRUE(*o38r == 42);
int i = 42;
m5::stl::optional<int &> o39 = i;
o39.map([](int &x) { x = 12; });
EXPECT_TRUE(i == 12);
}
{
SCOPED_TRACE("map constexpr");
#if !defined(_MSC_VER) && defined(TL_OPTIONAL_CXX14)
// test each overload in turn
constexpr m5::stl::optional<int> o16 = 42;
constexpr auto o16r = o16.map(get_int);
STATIC_EXPECT_TRUE(*o16r == 42);
constexpr m5::stl::optional<int> o20 = 42;
constexpr auto o20r = std::move(o20).map(get_int);
STATIC_EXPECT_TRUE(*o20r == 42);
constexpr m5::stl::optional<int> o32 = m5::stl::nullopt;
constexpr auto o32r = o32.map(get_int);
STATIC_EXPECT_TRUE(!o32r);
constexpr m5::stl::optional<int> o36 = m5::stl::nullopt;
constexpr auto o36r = std::move(o36).map(get_int);
STATIC_EXPECT_TRUE(!o36r);
#endif
}
{ // lhs is empty
SCOPED_TRACE("transform");
m5::stl::optional<int> o1;
auto o1r = o1.transform([](int i) { return i + 2; });
STATIC_EXPECT_TRUE((std::is_same<decltype(o1r), m5::stl::optional<int>>::value));
EXPECT_TRUE(!o1r);
// lhs has value
m5::stl::optional<int> o2 = 40;
auto o2r = o2.transform([](int i) { return i + 2; });
STATIC_EXPECT_TRUE((std::is_same<decltype(o2r), m5::stl::optional<int>>::value));
EXPECT_TRUE(o2r.value() == 42);
struct rval_call_transform {
double operator()(int) &&
{
return 42.0;
};
};
// ensure that function object is forwarded
m5::stl::optional<int> o3 = 42;
auto o3r = o3.transform(rval_call_transform{});
STATIC_EXPECT_TRUE((std::is_same<decltype(o3r), m5::stl::optional<double>>::value));
EXPECT_TRUE(o3r.value() == 42);
// ensure that lhs is forwarded
m5::stl::optional<int> o4 = 40;
auto o4r = std::move(o4).transform([](int &&i) { return i + 2; });
STATIC_EXPECT_TRUE((std::is_same<decltype(o4r), m5::stl::optional<int>>::value));
EXPECT_TRUE(o4r.value() == 42);
// ensure that lhs is const-propagated
const m5::stl::optional<int> o5 = 40;
auto o5r = o5.transform([](const int &i) { return i + 2; });
STATIC_EXPECT_TRUE((std::is_same<decltype(o5r), m5::stl::optional<int>>::value));
EXPECT_TRUE(o5r.value() == 42);
// test void return
m5::stl::optional<int> o7 = 40;
auto f7 = [](const int &) { return; };
auto o7r = o7.transform(f7);
STATIC_EXPECT_TRUE((std::is_same<decltype(o7r), m5::stl::optional<m5::stl::monostate>>::value));
EXPECT_TRUE(o7r.has_value());
// test each overload in turn
m5::stl::optional<int> o8 = 42;
auto o8r = o8.transform([](int) { return 42; });
EXPECT_TRUE(*o8r == 42);
m5::stl::optional<int> o9 = 42;
auto o9r = o9.transform([](int) { return; });
EXPECT_TRUE(o9r);
m5::stl::optional<int> o12 = 42;
auto o12r = std::move(o12).transform([](int) { return 42; });
EXPECT_TRUE(*o12r == 42);
m5::stl::optional<int> o13 = 42;
auto o13r = std::move(o13).transform([](int) { return; });
EXPECT_TRUE(o13r);
const m5::stl::optional<int> o16 = 42;
auto o16r = o16.transform([](int) { return 42; });
EXPECT_TRUE(*o16r == 42);
const m5::stl::optional<int> o17 = 42;
auto o17r = o17.transform([](int) { return; });
EXPECT_TRUE(o17r);
const m5::stl::optional<int> o20 = 42;
auto o20r = std::move(o20).transform([](int) { return 42; });
EXPECT_TRUE(*o20r == 42);
const m5::stl::optional<int> o21 = 42;
auto o21r = std::move(o21).transform([](int) { return; });
EXPECT_TRUE(o21r);
m5::stl::optional<int> o24 = m5::stl::nullopt;
auto o24r = o24.transform([](int) { return 42; });
EXPECT_TRUE(!o24r);
m5::stl::optional<int> o25 = m5::stl::nullopt;
auto o25r = o25.transform([](int) { return; });
EXPECT_TRUE(!o25r);
m5::stl::optional<int> o28 = m5::stl::nullopt;
auto o28r = std::move(o28).transform([](int) { return 42; });
EXPECT_TRUE(!o28r);
m5::stl::optional<int> o29 = m5::stl::nullopt;
auto o29r = std::move(o29).transform([](int) { return; });
EXPECT_TRUE(!o29r);
const m5::stl::optional<int> o32 = m5::stl::nullopt;
auto o32r = o32.transform([](int) { return 42; });
EXPECT_TRUE(!o32r);
const m5::stl::optional<int> o33 = m5::stl::nullopt;
auto o33r = o33.transform([](int) { return; });
EXPECT_TRUE(!o33r);
const m5::stl::optional<int> o36 = m5::stl::nullopt;
auto o36r = std::move(o36).transform([](int) { return 42; });
EXPECT_TRUE(!o36r);
const m5::stl::optional<int> o37 = m5::stl::nullopt;
auto o37r = std::move(o37).transform([](int) { return; });
EXPECT_TRUE(!o37r);
// callable which returns a reference
m5::stl::optional<int> o38 = 42;
auto o38r = o38.transform([](int &i) -> const int &{ return i; });
EXPECT_TRUE(o38r);
EXPECT_TRUE(*o38r == 42);
int i = 42;
m5::stl::optional<int &> o39 = i;
o39.transform([](int &x) { x = 12; });
EXPECT_TRUE(i == 12);
}
{
SCOPED_TRACE("transform constexpr");
#if !defined(_MSC_VER) && defined(TL_OPTIONAL_CXX14)
// test each overload in turn
constexpr m5::stl::optional<int> o16 = 42;
constexpr auto o16r = o16.transform(get_int);
STATIC_EXPECT_TRUE(*o16r == 42);
constexpr m5::stl::optional<int> o20 = 42;
constexpr auto o20r = std::move(o20).transform(get_int);
STATIC_EXPECT_TRUE(*o20r == 42);
constexpr m5::stl::optional<int> o32 = m5::stl::nullopt;
constexpr auto o32r = o32.transform(get_int);
STATIC_EXPECT_TRUE(!o32r);
constexpr m5::stl::optional<int> o36 = m5::stl::nullopt;
constexpr auto o36r = std::move(o36).transform(get_int);
STATIC_EXPECT_TRUE(!o36r);
#endif
}
{
SCOPED_TRACE("and_then");
// lhs is empty
m5::stl::optional<int> o1;
auto o1r = o1.and_then([](int) { return m5::stl::optional<float>{42}; });
STATIC_EXPECT_TRUE((std::is_same<decltype(o1r), m5::stl::optional<float>>::value));
EXPECT_TRUE(!o1r);
// lhs has value
m5::stl::optional<int> o2 = 12;
auto o2r = o2.and_then([](int) { return m5::stl::optional<float>{42}; });
STATIC_EXPECT_TRUE((std::is_same<decltype(o2r), m5::stl::optional<float>>::value));
EXPECT_TRUE(o2r.value() == 42.f);
// lhs is empty, rhs returns empty
m5::stl::optional<int> o3;
auto o3r = o3.and_then([](int) { return m5::stl::optional<float>{}; });
STATIC_EXPECT_TRUE((std::is_same<decltype(o3r), m5::stl::optional<float>>::value));
EXPECT_TRUE(!o3r);
// rhs returns empty
m5::stl::optional<int> o4 = 12;
auto o4r = o4.and_then([](int) { return m5::stl::optional<float>{}; });
STATIC_EXPECT_TRUE((std::is_same<decltype(o4r), m5::stl::optional<float>>::value));
EXPECT_TRUE(!o4r);
struct rval_call_and_then {
m5::stl::optional<double> operator()(int) &&
{
return m5::stl::optional<double>(42.0);
};
};
// ensure that function object is forwarded
m5::stl::optional<int> o5 = 42;
auto o5r = o5.and_then(rval_call_and_then{});
STATIC_EXPECT_TRUE((std::is_same<decltype(o5r), m5::stl::optional<double>>::value));
EXPECT_TRUE(o5r.value() == 42);
// ensure that lhs is forwarded
m5::stl::optional<int> o6 = 42;
auto o6r = std::move(o6).and_then([](int &&i) { return m5::stl::optional<double>(i); });
STATIC_EXPECT_TRUE((std::is_same<decltype(o6r), m5::stl::optional<double>>::value));
EXPECT_TRUE(o6r.value() == 42);
// ensure that function object is const-propagated
const m5::stl::optional<int> o7 = 42;
auto o7r = o7.and_then([](const int &i) { return m5::stl::optional<double>(i); });
STATIC_EXPECT_TRUE((std::is_same<decltype(o7r), m5::stl::optional<double>>::value));
EXPECT_TRUE(o7r.value() == 42);
// test each overload in turn
m5::stl::optional<int> o8 = 42;
auto o8r = o8.and_then([](int) { return m5::stl::make_optional(42); });
EXPECT_TRUE(*o8r == 42);
m5::stl::optional<int> o9 = 42;
auto o9r = std::move(o9).and_then([](int) { return m5::stl::make_optional(42); });
EXPECT_TRUE(*o9r == 42);
const m5::stl::optional<int> o10 = 42;
auto o10r = o10.and_then([](int) { return m5::stl::make_optional(42); });
EXPECT_TRUE(*o10r == 42);
const m5::stl::optional<int> o11 = 42;
auto o11r = std::move(o11).and_then([](int) { return m5::stl::make_optional(42); });
EXPECT_TRUE(*o11r == 42);
m5::stl::optional<int> o16 = m5::stl::nullopt;
auto o16r = o16.and_then([](int) { return m5::stl::make_optional(42); });
EXPECT_TRUE(!o16r);
m5::stl::optional<int> o17 = m5::stl::nullopt;
auto o17r = std::move(o17).and_then([](int) { return m5::stl::make_optional(42); });
EXPECT_TRUE(!o17r);
const m5::stl::optional<int> o18 = m5::stl::nullopt;
auto o18r = o18.and_then([](int) { return m5::stl::make_optional(42); });
EXPECT_TRUE(!o18r);
const m5::stl::optional<int> o19 = m5::stl::nullopt;
auto o19r = std::move(o19).and_then([](int) { return m5::stl::make_optional(42); });
EXPECT_TRUE(!o19r);
int i = 3;
m5::stl::optional<int &> o20{i};
std::move(o20).and_then([](int &r) { return m5::stl::optional<int &>{++r}; });
EXPECT_TRUE(o20);
EXPECT_TRUE(i == 4);
}
{
SCOPED_TRACE("constexpr and_then");
#if !defined(_MSC_VER) && defined(TL_OPTIONAL_CXX14)
constexpr m5::stl::optional<int> o10 = 42;
constexpr auto o10r = o10.and_then(get_opt_int);
EXPECT_TRUE(*o10r == 42);
constexpr m5::stl::optional<int> o11 = 42;
constexpr auto o11r = std::move(o11).and_then(get_opt_int);
EXPECT_TRUE(*o11r == 42);
constexpr m5::stl::optional<int> o18 = m5::stl::nullopt;
constexpr auto o18r = o18.and_then(get_opt_int);
EXPECT_TRUE(!o18r);
constexpr m5::stl::optional<int> o19 = m5::stl::nullopt;
constexpr auto o19r = std::move(o19).and_then(get_opt_int);
EXPECT_TRUE(!o19r);
#endif
}
{
SCOPED_TRACE("or else");
m5::stl::optional<int> o1 = 42;
EXPECT_TRUE(*(o1.or_else([] { return m5::stl::make_optional(13); })) == 42);
m5::stl::optional<int> o2;
EXPECT_TRUE(*(o2.or_else([] { return m5::stl::make_optional(13); })) == 13);
}
{
SCOPED_TRACE("disjunction");
m5::stl::optional<int> o1 = 42;
m5::stl::optional<int> o2 = 12;
m5::stl::optional<int> o3;
EXPECT_TRUE(*o1.disjunction(o2) == 42);
EXPECT_TRUE(*o1.disjunction(o3) == 42);
EXPECT_TRUE(*o2.disjunction(o1) == 12);
EXPECT_TRUE(*o2.disjunction(o3) == 12);
EXPECT_TRUE(*o3.disjunction(o1) == 42);
EXPECT_TRUE(*o3.disjunction(o2) == 12);
}
{
SCOPED_TRACE("conjunction");
m5::stl::optional<int> o1 = 42;
EXPECT_TRUE(*o1.conjunction(42.0) == 42.0);
EXPECT_TRUE(*o1.conjunction(std::string{"hello"}) == std::string{"hello"});
m5::stl::optional<int> o2;
EXPECT_TRUE(!o2.conjunction(42.0));
EXPECT_TRUE(!o2.conjunction(std::string{"hello"}));
}
{
SCOPED_TRACE("map_or");
m5::stl::optional<int> o1 = 21;
EXPECT_TRUE((o1.map_or([](int x) { return x * 2; }, 13)) == 42);
m5::stl::optional<int> o2;
EXPECT_TRUE((o2.map_or([](int x) { return x * 2; }, 13)) == 13);
}
{
SCOPED_TRACE("map_or_else");
m5::stl::optional<int> o1 = 21;
EXPECT_TRUE((o1.map_or_else([](int x) { return x * 2; }, [] { return 13; })) == 42);
m5::stl::optional<int> o2;
EXPECT_TRUE((o2.map_or_else([](int x) { return x * 2; }, [] { return 13; })) == 13);
}
{
SCOPED_TRACE("take");
m5::stl::optional<int> o1 = 42;
EXPECT_TRUE(*o1.take() == 42);
EXPECT_TRUE(!o1);
m5::stl::optional<int> o2;
EXPECT_TRUE(!o2.take());
EXPECT_TRUE(!o2);
}
struct foo {
void non_const()
{
}
};
#if defined(TL_OPTIONAL_CXX14) && !defined(TL_OPTIONAL_GCC49) && !defined(TL_OPTIONAL_GCC54) && \
!defined(TL_OPTIONAL_GCC55)
{
SCOPED_TRACE("Issue #1");
m5::stl::optional<foo> f = foo{};
auto l = [](auto &&x) { x.non_const(); };
f.map(l);
}
#endif
struct overloaded {
m5::stl::optional<int> operator()(foo &)
{
return 0;
}
m5::stl::optional<std::string> operator()(const foo &)
{
return "";
}
};
{
SCOPED_TRACE("Issue #2");
m5::stl::optional<foo> f = foo{};
auto x = f.and_then(overloaded{});
}
};

View file

@ -0,0 +1,6 @@
#include <gtest/gtest.h>
#include <m5_utility/stl/optional.hpp>
TEST(Optional, Hashing)
{
}

View file

@ -0,0 +1,45 @@
#include <gtest/gtest.h>
#include <m5_utility/stl/optional.hpp>
#include <tuple>
#include <vector>
namespace in_place {
struct takes_init_and_variadic {
std::vector<int> v;
std::tuple<int, int> t;
template <class... Args>
takes_init_and_variadic(std::initializer_list<int> l, Args &&...args) : v(l), t(std::forward<Args>(args)...)
{
}
};
} // namespace in_place
TEST(Optional, Inplace)
{
m5::stl::optional<int> o1{m5::stl::in_place};
m5::stl::optional<int> o2(m5::stl::in_place);
EXPECT_TRUE(o1);
EXPECT_TRUE(o1 == 0);
EXPECT_TRUE(o2);
EXPECT_TRUE(o2 == 0);
m5::stl::optional<int> o3(m5::stl::in_place, 42);
EXPECT_TRUE(o3 == 42);
m5::stl::optional<std::tuple<int, int>> o4(m5::stl::in_place, 0, 1);
EXPECT_TRUE(o4);
EXPECT_TRUE(std::get<0>(*o4) == 0);
EXPECT_TRUE(std::get<1>(*o4) == 1);
m5::stl::optional<std::vector<int>> o5(m5::stl::in_place, {0, 1});
EXPECT_TRUE(o5);
EXPECT_TRUE((*o5)[0] == 0);
EXPECT_TRUE((*o5)[1] == 1);
m5::stl::optional<in_place::takes_init_and_variadic> o6(m5::stl::in_place, {0, 1}, 2, 3);
EXPECT_TRUE(o6->v[0] == 0);
EXPECT_TRUE(o6->v[1] == 1);
EXPECT_TRUE(std::get<0>(o6->t) == 2);
EXPECT_TRUE(std::get<1>(o6->t) == 3);
}

View file

@ -0,0 +1,59 @@
#include <gtest/gtest.h>
#include <m5_utility/stl/optional.hpp>
#include <type_traits>
namespace issues {
struct foo {
int& v()
{
return i;
}
int i = 0;
};
} // namespace issues
int& x(int& i)
{
i = 42;
return i;
}
TEST(Optional, issue14)
{
m5::stl::optional<issues::foo> f = issues::foo{};
auto v = f.map(&issues::foo::v).map(x);
static_assert(std::is_same<decltype(v), m5::stl::optional<int&>>::value, "Must return a reference");
EXPECT_TRUE(f->i == 42);
EXPECT_TRUE(*v == 42);
EXPECT_TRUE((&f->i) == (&*v));
}
struct fail_on_copy_self {
int value;
fail_on_copy_self(int v) : value(v)
{
}
fail_on_copy_self(const fail_on_copy_self& other) : value(other.value)
{
EXPECT_TRUE(&other != this);
}
};
TEST(Optional, issue15)
{
m5::stl::optional<fail_on_copy_self> o = fail_on_copy_self(42);
o = o;
EXPECT_TRUE(o->value == 42);
}
TEST(Optional, issue33)
{
int i = 0;
int j = 0;
m5::stl::optional<int&> a = i;
a.emplace(j);
*a = 42;
EXPECT_TRUE(j == 42);
EXPECT_TRUE(*a == 42);
EXPECT_TRUE(a.has_value());
}

View file

@ -0,0 +1,49 @@
#include <gtest/gtest.h>
#include <m5_utility/stl/optional.hpp>
#include <tuple>
#include <vector>
namespace make_opt {
struct takes_init_and_variadic {
std::vector<int> v;
std::tuple<int, int> t;
template <class... Args>
takes_init_and_variadic(std::initializer_list<int> l, Args &&...args) : v(l), t(std::forward<Args>(args)...)
{
}
};
} // namespace make_opt
TEST(Optional, MakeOptional)
{
auto o1 = m5::stl::make_optional(42);
auto o2 = m5::stl::optional<int>(42);
constexpr bool is_same = std::is_same<decltype(o1), m5::stl::optional<int>>::value;
EXPECT_TRUE(is_same);
EXPECT_TRUE(o1 == o2);
auto o3 = m5::stl::make_optional<std::tuple<int, int, int, int>>(0, 1, 2, 3);
EXPECT_TRUE(std::get<0>(*o3) == 0);
EXPECT_TRUE(std::get<1>(*o3) == 1);
EXPECT_TRUE(std::get<2>(*o3) == 2);
EXPECT_TRUE(std::get<3>(*o3) == 3);
auto o4 = m5::stl::make_optional<std::vector<int>>({0, 1, 2, 3});
EXPECT_TRUE(o4.value()[0] == 0);
EXPECT_TRUE(o4.value()[1] == 1);
EXPECT_TRUE(o4.value()[2] == 2);
EXPECT_TRUE(o4.value()[3] == 3);
auto o5 = m5::stl::make_optional<make_opt::takes_init_and_variadic>({0, 1}, 2, 3);
EXPECT_TRUE(o5->v[0] == 0);
EXPECT_TRUE(o5->v[1] == 1);
EXPECT_TRUE(std::get<0>(o5->t) == 2);
EXPECT_TRUE(std::get<1>(o5->t) == 3);
auto i = 42;
auto o6 = m5::stl::make_optional<int &>(i);
EXPECT_TRUE((std::is_same<decltype(o6), m5::stl::optional<int &>>::value));
EXPECT_TRUE(o6);
EXPECT_TRUE(*o6 == 42);
}

View file

@ -0,0 +1,119 @@
#include <gtest/gtest.h>
#include <m5_utility/stl/optional.hpp>
TEST(Optional, Noexcept)
{
m5::stl::optional<int> o1{4};
m5::stl::optional<int> o2{42};
{
SCOPED_TRACE("comparison with nullopt");
EXPECT_TRUE(noexcept(o1 == m5::stl::nullopt));
EXPECT_TRUE(noexcept(m5::stl::nullopt == o1));
EXPECT_TRUE(noexcept(o1 != m5::stl::nullopt));
EXPECT_TRUE(noexcept(m5::stl::nullopt != o1));
EXPECT_TRUE(noexcept(o1 < m5::stl::nullopt));
EXPECT_TRUE(noexcept(m5::stl::nullopt < o1));
EXPECT_TRUE(noexcept(o1 <= m5::stl::nullopt));
EXPECT_TRUE(noexcept(m5::stl::nullopt <= o1));
EXPECT_TRUE(noexcept(o1 > m5::stl::nullopt));
EXPECT_TRUE(noexcept(m5::stl::nullopt > o1));
EXPECT_TRUE(noexcept(o1 >= m5::stl::nullopt));
EXPECT_TRUE(noexcept(m5::stl::nullopt >= o1));
}
{
SCOPED_TRACE("swap");
// TODO see why this fails
#if !defined(_MSC_VER) || _MSC_VER > 1900
EXPECT_TRUE(noexcept(swap(o1, o2)) == noexcept(o1.swap(o2)));
struct nothrow_swappable {
nothrow_swappable &swap(const nothrow_swappable &) noexcept
{
return *this;
}
};
struct throw_swappable {
throw_swappable() = default;
throw_swappable(const throw_swappable &)
{
}
throw_swappable(throw_swappable &&)
{
}
throw_swappable &swap(const throw_swappable &)
{
return *this;
}
};
m5::stl::optional<nothrow_swappable> ont;
m5::stl::optional<throw_swappable> ot;
EXPECT_TRUE(noexcept(ont.swap(ont)));
EXPECT_TRUE(!noexcept(ot.swap(ot)));
#endif
}
{
SCOPED_TRACE("constructors");
// TODO see why this fails
#if !defined(_MSC_VER) || _MSC_VER > 1900
EXPECT_TRUE(noexcept(m5::stl::optional<int>{}));
EXPECT_TRUE(noexcept(m5::stl::optional<int>{m5::stl::nullopt}));
struct nothrow_move {
nothrow_move(nothrow_move &&) noexcept = default;
};
struct throw_move {
throw_move(throw_move &&)
{
}
};
using nothrow_opt = m5::stl::optional<nothrow_move>;
using throw_opt = m5::stl::optional<throw_move>;
EXPECT_TRUE(std::is_nothrow_move_constructible<nothrow_opt>::value);
EXPECT_TRUE(!std::is_nothrow_move_constructible<throw_opt>::value);
#endif
}
{
SCOPED_TRACE("assignment");
EXPECT_TRUE(noexcept(o1 = m5::stl::nullopt));
struct nothrow_move_assign {
nothrow_move_assign() = default;
nothrow_move_assign(nothrow_move_assign &&) noexcept = default;
nothrow_move_assign &operator=(const nothrow_move_assign &) = default;
};
struct throw_move_assign {
throw_move_assign() = default;
throw_move_assign(throw_move_assign &&)
{
}
throw_move_assign &operator=(const throw_move_assign &)
{
return *this;
}
};
using nothrow_opt = m5::stl::optional<nothrow_move_assign>;
using throw_opt = m5::stl::optional<throw_move_assign>;
EXPECT_TRUE(noexcept(std::declval<nothrow_opt>() = std::declval<nothrow_opt>()));
EXPECT_TRUE(!noexcept(std::declval<throw_opt>() = std::declval<throw_opt>()));
}
{
SCOPED_TRACE("observers");
EXPECT_TRUE(noexcept(static_cast<bool>(o1)));
EXPECT_TRUE(noexcept(o1.has_value()));
}
{
SCOPED_TRACE("modifiers");
EXPECT_TRUE(noexcept(o1.reset()));
}
}

View file

@ -0,0 +1,17 @@
#include <gtest/gtest.h>
#include <m5_utility/stl/optional.hpp>
TEST(Optional, Nullopt)
{
m5::stl::optional<int> o1 = m5::stl::nullopt;
m5::stl::optional<int> o2{m5::stl::nullopt};
m5::stl::optional<int> o3(m5::stl::nullopt);
m5::stl::optional<int> o4 = {m5::stl::nullopt};
EXPECT_TRUE(!o1);
EXPECT_TRUE(!o2);
EXPECT_TRUE(!o3);
EXPECT_TRUE(!o4);
EXPECT_TRUE(!std::is_default_constructible<m5::stl::nullopt_t>::value);
}

View file

@ -0,0 +1,39 @@
#include <gtest/gtest.h>
#include <m5_utility/stl/optional.hpp>
struct move_detector {
move_detector() = default;
move_detector(move_detector &&rhs)
{
rhs.been_moved = true;
}
bool been_moved = false;
};
TEST(Optional, Observers)
{
m5::stl::optional<int> o1 = 42;
m5::stl::optional<int> o2;
const m5::stl::optional<int> o3 = 42;
EXPECT_TRUE(*o1 == 42);
EXPECT_TRUE(*o1 == o1.value());
EXPECT_TRUE(o2.value_or(42) == 42);
EXPECT_TRUE(o3.value() == 42);
auto success = std::is_same<decltype(o1.value()), int &>::value;
EXPECT_TRUE(success);
success = std::is_same<decltype(o3.value()), const int &>::value;
EXPECT_TRUE(success);
success = std::is_same<decltype(std::move(o1).value()), int &&>::value;
EXPECT_TRUE(success);
#ifndef TL_OPTIONAL_NO_CONSTRR
success = std::is_same<decltype(std::move(o3).value()), const int &&>::value;
EXPECT_TRUE(success);
#endif
m5::stl::optional<move_detector> o4{m5::stl::in_place};
move_detector o5 = std::move(o4).value();
EXPECT_TRUE(o4->been_moved);
EXPECT_TRUE(!o5.been_moved);
}

View file

@ -0,0 +1,154 @@
#include <gtest/gtest.h>
#include <m5_utility/stl/optional.hpp>
TEST(Optional, RelationalOps)
{
m5::stl::optional<int> o1{4};
m5::stl::optional<int> o2{42};
m5::stl::optional<int> o3{};
{
SCOPED_TRACE("self simple");
EXPECT_TRUE(!(o1 == o2));
EXPECT_TRUE(o1 == o1);
EXPECT_TRUE(o1 != o2);
EXPECT_TRUE(!(o1 != o1));
EXPECT_TRUE(o1 < o2);
EXPECT_TRUE(!(o1 < o1));
EXPECT_TRUE(!(o1 > o2));
EXPECT_TRUE(!(o1 > o1));
EXPECT_TRUE(o1 <= o2);
EXPECT_TRUE(o1 <= o1);
EXPECT_TRUE(!(o1 >= o2));
EXPECT_TRUE(o1 >= o1);
}
{
SCOPED_TRACE("nullopt simple");
EXPECT_TRUE(!(o1 == m5::stl::nullopt));
EXPECT_TRUE(!(m5::stl::nullopt == o1));
EXPECT_TRUE(o1 != m5::stl::nullopt);
EXPECT_TRUE(m5::stl::nullopt != o1);
EXPECT_TRUE(!(o1 < m5::stl::nullopt));
EXPECT_TRUE(m5::stl::nullopt < o1);
EXPECT_TRUE(o1 > m5::stl::nullopt);
EXPECT_TRUE(!(m5::stl::nullopt > o1));
EXPECT_TRUE(!(o1 <= m5::stl::nullopt));
EXPECT_TRUE(m5::stl::nullopt <= o1);
EXPECT_TRUE(o1 >= m5::stl::nullopt);
EXPECT_TRUE(!(m5::stl::nullopt >= o1));
EXPECT_TRUE(o3 == m5::stl::nullopt);
EXPECT_TRUE(m5::stl::nullopt == o3);
EXPECT_TRUE(!(o3 != m5::stl::nullopt));
EXPECT_TRUE(!(m5::stl::nullopt != o3));
EXPECT_TRUE(!(o3 < m5::stl::nullopt));
EXPECT_TRUE(!(m5::stl::nullopt < o3));
EXPECT_TRUE(!(o3 > m5::stl::nullopt));
EXPECT_TRUE(!(m5::stl::nullopt > o3));
EXPECT_TRUE(o3 <= m5::stl::nullopt);
EXPECT_TRUE(m5::stl::nullopt <= o3);
EXPECT_TRUE(o3 >= m5::stl::nullopt);
EXPECT_TRUE(m5::stl::nullopt >= o3);
}
{
SCOPED_TRACE("with T simple");
EXPECT_TRUE(!(o1 == 1));
EXPECT_TRUE(!(1 == o1));
EXPECT_TRUE(o1 != 1);
EXPECT_TRUE(1 != o1);
EXPECT_TRUE(!(o1 < 1));
EXPECT_TRUE(1 < o1);
EXPECT_TRUE(o1 > 1);
EXPECT_TRUE(!(1 > o1));
EXPECT_TRUE(!(o1 <= 1));
EXPECT_TRUE(1 <= o1);
EXPECT_TRUE(o1 >= 1);
EXPECT_TRUE(!(1 >= o1));
EXPECT_TRUE(o1 == 4);
EXPECT_TRUE(4 == o1);
EXPECT_TRUE(!(o1 != 4));
EXPECT_TRUE(!(4 != o1));
EXPECT_TRUE(!(o1 < 4));
EXPECT_TRUE(!(4 < o1));
EXPECT_TRUE(!(o1 > 4));
EXPECT_TRUE(!(4 > o1));
EXPECT_TRUE(o1 <= 4);
EXPECT_TRUE(4 <= o1);
EXPECT_TRUE(o1 >= 4);
EXPECT_TRUE(4 >= o1);
}
m5::stl::optional<std::string> o4{"hello"};
m5::stl::optional<std::string> o5{"xyz"};
{
SCOPED_TRACE("self complex");
EXPECT_TRUE(!(o4 == o5));
EXPECT_TRUE(o4 == o4);
EXPECT_TRUE(o4 != o5);
EXPECT_TRUE(!(o4 != o4));
EXPECT_TRUE(o4 < o5);
EXPECT_TRUE(!(o4 < o4));
EXPECT_TRUE(!(o4 > o5));
EXPECT_TRUE(!(o4 > o4));
EXPECT_TRUE(o4 <= o5);
EXPECT_TRUE(o4 <= o4);
EXPECT_TRUE(!(o4 >= o5));
EXPECT_TRUE(o4 >= o4);
}
{
SCOPED_TRACE("nullopt complex");
EXPECT_TRUE(!(o4 == m5::stl::nullopt));
EXPECT_TRUE(!(m5::stl::nullopt == o4));
EXPECT_TRUE(o4 != m5::stl::nullopt);
EXPECT_TRUE(m5::stl::nullopt != o4);
EXPECT_TRUE(!(o4 < m5::stl::nullopt));
EXPECT_TRUE(m5::stl::nullopt < o4);
EXPECT_TRUE(o4 > m5::stl::nullopt);
EXPECT_TRUE(!(m5::stl::nullopt > o4));
EXPECT_TRUE(!(o4 <= m5::stl::nullopt));
EXPECT_TRUE(m5::stl::nullopt <= o4);
EXPECT_TRUE(o4 >= m5::stl::nullopt);
EXPECT_TRUE(!(m5::stl::nullopt >= o4));
EXPECT_TRUE(o3 == m5::stl::nullopt);
EXPECT_TRUE(m5::stl::nullopt == o3);
EXPECT_TRUE(!(o3 != m5::stl::nullopt));
EXPECT_TRUE(!(m5::stl::nullopt != o3));
EXPECT_TRUE(!(o3 < m5::stl::nullopt));
EXPECT_TRUE(!(m5::stl::nullopt < o3));
EXPECT_TRUE(!(o3 > m5::stl::nullopt));
EXPECT_TRUE(!(m5::stl::nullopt > o3));
EXPECT_TRUE(o3 <= m5::stl::nullopt);
EXPECT_TRUE(m5::stl::nullopt <= o3);
EXPECT_TRUE(o3 >= m5::stl::nullopt);
EXPECT_TRUE(m5::stl::nullopt >= o3);
}
{
SCOPED_TRACE("with T complex");
EXPECT_TRUE(!(o4 == "a"));
EXPECT_TRUE(!("a" == o4));
EXPECT_TRUE(o4 != "a");
EXPECT_TRUE("a" != o4);
EXPECT_TRUE(!(o4 < "a"));
EXPECT_TRUE("a" < o4);
EXPECT_TRUE(o4 > "a");
EXPECT_TRUE(!("a" > o4));
EXPECT_TRUE(!(o4 <= "a"));
EXPECT_TRUE("a" <= o4);
EXPECT_TRUE(o4 >= "a");
EXPECT_TRUE(!("a" >= o4));
EXPECT_TRUE(o4 == "hello");
EXPECT_TRUE("hello" == o4);
EXPECT_TRUE(!(o4 != "hello"));
EXPECT_TRUE(!("hello" != o4));
EXPECT_TRUE(!(o4 < "hello"));
EXPECT_TRUE(!("hello" < o4));
EXPECT_TRUE(!(o4 > "hello"));
EXPECT_TRUE(!("hello" > o4));
EXPECT_TRUE(o4 <= "hello");
EXPECT_TRUE("hello" <= o4);
EXPECT_TRUE(o4 >= "hello");
EXPECT_TRUE("hello" >= o4);
}
}

View file

@ -0,0 +1,29 @@
#include <gtest/gtest.h>
#include <m5_utility/stl/optional.hpp>
TEST(Optional, SwapValue)
{
m5::stl::optional<int> o1 = 42;
m5::stl::optional<int> o2 = 12;
o1.swap(o2);
EXPECT_TRUE(o1.value() == 12);
EXPECT_TRUE(o2.value() == 42);
}
TEST(Optional, SwapValueWithNullIntialized)
{
m5::stl::optional<int> o1 = 42;
m5::stl::optional<int> o2 = m5::stl::nullopt;
o1.swap(o2);
EXPECT_TRUE(!o1.has_value());
EXPECT_TRUE(o2.value() == 42);
}
TEST(Optional, SwapNullIntializedWithValue)
{
m5::stl::optional<int> o1 = m5::stl::nullopt;
m5::stl::optional<int> o2 = 42;
o1.swap(o2);
EXPECT_TRUE(o1.value() == 42);
EXPECT_TRUE(!o2.has_value());
}