| @@ -1,6 +1,6 @@ | |||||
| #pragma once | #pragma once | ||||
| #include <cppcore/conversion.h> | |||||
| #include <cppcore/define.h> | |||||
| #include <cppcore/misc.h> | |||||
| #include <cppcore/threading.h> | |||||
| #include "cppcore/conversion.h" | |||||
| #include "cppcore/define.h" | |||||
| #include "cppcore/misc.h" | |||||
| #include "cppcore/threading.h" | |||||
| @@ -1,6 +1,6 @@ | |||||
| #pragma once | #pragma once | ||||
| #include <cppcore/conversion/byteorder.h> | |||||
| #include <cppcore/conversion/enum.h> | |||||
| #include <cppcore/conversion/string.h> | |||||
| #include <cppcore/conversion/time.h> | |||||
| #include "conversion/byteorder.h" | |||||
| #include "conversion/enum.h" | |||||
| #include "conversion/string.h" | |||||
| #include "conversion/time.h" | |||||
| @@ -1,8 +1,8 @@ | |||||
| #pragma once | #pragma once | ||||
| #include <cppcore/misc/exception.h> | |||||
| #include <cppcore/misc/flags.h> | |||||
| #include <cppcore/misc/indent.h> | |||||
| #include <cppcore/misc/stream.h> | |||||
| #include <cppcore/misc/typehelper.h> | |||||
| #include <cppcore/misc/utils.h> | |||||
| #include "misc/exception.h" | |||||
| #include "misc/flags.h" | |||||
| #include "misc/indent.h" | |||||
| #include "misc/stream.h" | |||||
| #include "misc/typehelper.h" | |||||
| #include "misc/utils.h" | |||||
| @@ -7,64 +7,76 @@ namespace cppcore | |||||
| namespace __impl | namespace __impl | ||||
| { | { | ||||
| constexpr long default_indent = 4; | constexpr long default_indent = 4; | ||||
| inline int indent_stream_index() | |||||
| { | |||||
| static const int value = std::ios::xalloc(); | |||||
| return value; | |||||
| } | |||||
| /** | |||||
| * @brief Returns the index where the indention value is stored inside the stream. | |||||
| */ | |||||
| inline int indent_stream_index(); | |||||
| inline int indent_count_stream_index() | |||||
| { | |||||
| static const int value = std::ios::xalloc(); | |||||
| return value; | |||||
| } | |||||
| /** | |||||
| * @brief Returns the index where the current indention level is stored inside the stream. | |||||
| */ | |||||
| inline int indent_level_stream_index(); | |||||
| /** | |||||
| * @brief Helper class to set the stream indention. | |||||
| */ | |||||
| struct set_indent_impl | struct set_indent_impl | ||||
| { int value; }; | { int value; }; | ||||
| } | } | ||||
| inline auto setindent(int value) | |||||
| { return __impl::set_indent_impl { value }; } | |||||
| /** | |||||
| * @brief Set the indention of a stream. | |||||
| * | |||||
| * @param[in] value New indention value. | |||||
| * | |||||
| * @return Helper class to set the indention value. | |||||
| */ | |||||
| inline auto setindent(int value); | |||||
| inline std::ostream& incindent(std::ostream& os) | |||||
| { | |||||
| ++os.iword(__impl::indent_stream_index()); | |||||
| return os; | |||||
| } | |||||
| /** | |||||
| * @brief Increment the current indention level by one. | |||||
| * | |||||
| * @param[in] os Stream to increment the indention level for. | |||||
| * | |||||
| * @return Stream passed to this function. | |||||
| */ | |||||
| inline std::ostream& incindent(std::ostream& os); | |||||
| inline std::ostream& decindent(std::ostream& os) | |||||
| { | |||||
| auto& indent = os.iword(__impl::indent_stream_index()); | |||||
| if (--indent < 0) | |||||
| indent = 0; | |||||
| return os; | |||||
| } | |||||
| /** | |||||
| * @brief Decrement the current indention level by one. | |||||
| * | |||||
| * @param[in] os Stream to decrement the indention level for. | |||||
| * | |||||
| * @return Stream passed to this function. | |||||
| */ | |||||
| inline std::ostream& decindent(std::ostream& os); | |||||
| inline std::ostream& indent(std::ostream& os) | |||||
| { | |||||
| auto i = os.iword(__impl::indent_stream_index()); | |||||
| auto c = __impl::default_indent + os.iword(__impl::indent_count_stream_index()); | |||||
| i *= c; | |||||
| if (i >= 0) | |||||
| { | |||||
| os << std::endl; | |||||
| while (i--) | |||||
| os.put(' '); | |||||
| } | |||||
| return os; | |||||
| } | |||||
| /** | |||||
| * @brief Add a line break and indention to the stream. | |||||
| * | |||||
| * @param[in] os Stream to decrement the indention level for. | |||||
| * | |||||
| * @return Stream passed to this function. | |||||
| */ | |||||
| inline std::ostream& indent(std::ostream& os); | |||||
| } | } | ||||
| namespace std | namespace std | ||||
| { | { | ||||
| /** | |||||
| * @brief Write the helper class to stream using the << operator. | |||||
| */ | |||||
| template<typename T_char, typename T_traits> | template<typename T_char, typename T_traits> | ||||
| inline basic_ostream<T_char, T_traits>& operator<< (basic_ostream<T_char, T_traits>& os, const cppcore::__impl::set_indent_impl& i) | |||||
| { | |||||
| using namespace ::cppcore; | |||||
| os.iword(__impl::indent_count_stream_index()) = i.value - __impl::default_indent; | |||||
| return os; | |||||
| } | |||||
| inline basic_ostream<T_char, T_traits>& operator<< ( | |||||
| basic_ostream<T_char, T_traits>& os, | |||||
| const cppcore::__impl::set_indent_impl& i); | |||||
| } | } | ||||
| #include "indent.inl" | |||||
| @@ -0,0 +1,69 @@ | |||||
| #pragma once | |||||
| #include "indent.h" | |||||
| namespace cppcore | |||||
| { | |||||
| namespace __impl | |||||
| { | |||||
| int indent_stream_index() | |||||
| { | |||||
| static const int value = std::ios::xalloc(); | |||||
| return value; | |||||
| } | |||||
| int indent_level_stream_index() | |||||
| { | |||||
| static const int value = std::ios::xalloc(); | |||||
| return value; | |||||
| } | |||||
| } | |||||
| auto setindent(int value) | |||||
| { return __impl::set_indent_impl { value }; } | |||||
| std::ostream& incindent(std::ostream& os) | |||||
| { | |||||
| ++os.iword(__impl::indent_stream_index()); | |||||
| return os; | |||||
| } | |||||
| std::ostream& decindent(std::ostream& os) | |||||
| { | |||||
| auto& indent = os.iword(__impl::indent_stream_index()); | |||||
| if (--indent < 0) | |||||
| indent = 0; | |||||
| return os; | |||||
| } | |||||
| std::ostream& indent(std::ostream& os) | |||||
| { | |||||
| auto i = os.iword(__impl::indent_stream_index()); | |||||
| auto c = __impl::default_indent + os.iword(__impl::indent_level_stream_index()); | |||||
| i *= c; | |||||
| if (i >= 0) | |||||
| { | |||||
| os << std::endl; | |||||
| while (i--) | |||||
| os.put(' '); | |||||
| } | |||||
| return os; | |||||
| } | |||||
| } | |||||
| namespace std | |||||
| { | |||||
| template<typename T_char, typename T_traits> | |||||
| inline basic_ostream<T_char, T_traits>& operator<< (basic_ostream<T_char, T_traits>& os, const cppcore::__impl::set_indent_impl& i) | |||||
| { | |||||
| using namespace ::cppcore; | |||||
| os.iword(__impl::indent_level_stream_index()) = i.value - __impl::default_indent; | |||||
| return os; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,262 @@ | |||||
| #pragma once | |||||
| #include <memory> | |||||
| #include "exception.h" | |||||
| namespace cppcore | |||||
| { | |||||
| template<typename T_value> | |||||
| struct nullable | |||||
| { | |||||
| public: | |||||
| using value_type = T_value; | |||||
| struct value_container | |||||
| { | |||||
| value_type value; | |||||
| template<class... T_args> | |||||
| inline value_container(T_args&&... p_args) | |||||
| : value(std::forward<T_args>(p_args)...) | |||||
| { } | |||||
| }; | |||||
| using value_container_ptr_u = std::unique_ptr<value_container>; | |||||
| private: | |||||
| value_container_ptr_u _container; | |||||
| public: | |||||
| /** | |||||
| * @brief Default constructor. | |||||
| */ | |||||
| inline nullable() = default; | |||||
| /** | |||||
| * @brief Construtor to create the object. Parameters will passed to the constructor of the value type. | |||||
| */ | |||||
| template<class... T_args> | |||||
| inline nullable(T_args&&... p_args) | |||||
| : _container(new value_container(std::forward<T_args>(p_args)...)) | |||||
| { } | |||||
| /** | |||||
| * @brief Copy constructor. | |||||
| */ | |||||
| inline nullable(nullable& other) | |||||
| : _container(other | |||||
| ? new value_container(*other) | |||||
| : nullptr) | |||||
| { } | |||||
| /** | |||||
| * @brief Copy constructor. | |||||
| */ | |||||
| inline nullable(const nullable& other) | |||||
| : _container(other | |||||
| ? new value_container(*other) | |||||
| : nullptr) | |||||
| { } | |||||
| /** | |||||
| * @brief Move constructor. | |||||
| */ | |||||
| inline nullable(nullable&& other) | |||||
| : _container(std::move(other)._container) | |||||
| { } | |||||
| public: | |||||
| /** | |||||
| * @brief Assignment constructor. | |||||
| */ | |||||
| inline decltype(auto) operator=(value_type&& t) | |||||
| { | |||||
| _container.reset(new value_container(std::forward<value_type>(t))); | |||||
| return *this; | |||||
| } | |||||
| /** | |||||
| * @brief Copy assignment constructor. | |||||
| */ | |||||
| inline decltype(auto) operator=(const nullable& other) | |||||
| { | |||||
| _container.reset(other | |||||
| ? new value_container(*other) | |||||
| : nullptr); | |||||
| return *this; | |||||
| } | |||||
| /** | |||||
| * @brief Move assignment constructor. | |||||
| */ | |||||
| inline decltype(auto) operator=(nullable&& other) | |||||
| { | |||||
| _container = std::move(other._container); | |||||
| return *this; | |||||
| } | |||||
| public: | |||||
| /** | |||||
| * @brief Get the stored value. | |||||
| */ | |||||
| inline value_type& value() | |||||
| { check(); return _container->value; } | |||||
| /** | |||||
| * @brief Get the stored value. | |||||
| */ | |||||
| inline const value_type& value() const | |||||
| { check(); return _container->value; } | |||||
| /** | |||||
| * @brief Check if the object has an value assigned. | |||||
| */ | |||||
| inline bool has_value() const | |||||
| { return static_cast<bool>(_container); } | |||||
| /** | |||||
| * @brief Reset the object. THis will release the stored value. | |||||
| */ | |||||
| inline void reset() | |||||
| { _container.reset(); } | |||||
| public: | |||||
| /** | |||||
| * @brief Operator to access the stored value. | |||||
| */ | |||||
| inline decltype(auto) operator*() | |||||
| { return value(); } | |||||
| /** | |||||
| * @brief Operator to access the stored value. | |||||
| */ | |||||
| inline decltype(auto) operator*() const | |||||
| { return value(); } | |||||
| /** | |||||
| * @brief Operator to access the stored value. | |||||
| */ | |||||
| inline decltype(auto) operator->() | |||||
| { return &value(); } | |||||
| /** | |||||
| * @brief Operator to access the stored value. | |||||
| */ | |||||
| inline decltype(auto) operator->() const | |||||
| { return &value(); } | |||||
| /** | |||||
| * @brief Operator to access the stored value. | |||||
| */ | |||||
| inline decltype(auto) operator()() | |||||
| { return value(); } | |||||
| /** | |||||
| * @brief Operator to access the soted value. | |||||
| */ | |||||
| inline decltype(auto) operator()() const | |||||
| { return value(); } | |||||
| /** | |||||
| * @brief Convert to boolean. | |||||
| */ | |||||
| inline explicit operator bool() const | |||||
| { return has_value(); } | |||||
| private: | |||||
| /** | |||||
| * @brief Check if the object has an value assigned. If not raise an exception. | |||||
| */ | |||||
| inline void check() const | |||||
| { | |||||
| if (!has_value()) | |||||
| throw invalid_operation_exception("nullable does not have a value"); | |||||
| } | |||||
| }; | |||||
| /* operator== */ | |||||
| template<typename T_nullable> | |||||
| inline bool operator==(const T_nullable& lhs, const typename T_nullable::value_type& rhs) | |||||
| { return lhs.has_value() && *lhs == rhs; } | |||||
| template<typename T_nullable> | |||||
| inline bool operator==(const typename T_nullable::value_type& lhs, const T_nullable& rhs) | |||||
| { return rhs.has_value() && lhs == *rhs; } | |||||
| template<typename T_nullable> | |||||
| inline bool operator==(const T_nullable& lhs, const T_nullable& rhs) | |||||
| { return lhs.has_value() && rhs.has_value() && *lhs == *rhs; } | |||||
| /* operator!= */ | |||||
| template<typename T_nullable> | |||||
| inline bool operator!=(const T_nullable& lhs, const typename T_nullable::value_type& rhs) | |||||
| { return lhs.has_value() && *lhs != rhs; } | |||||
| template<typename T_nullable> | |||||
| inline bool operator!=(const typename T_nullable::value_type& lhs, const T_nullable& rhs) | |||||
| { return rhs.has_value() && lhs != *rhs; } | |||||
| template<typename T_nullable> | |||||
| inline bool operator!=(const T_nullable& lhs, const T_nullable& rhs) | |||||
| { return lhs.has_value() && rhs.has_value() && *lhs != *rhs; } | |||||
| /* operator< */ | |||||
| template<typename T_nullable> | |||||
| inline bool operator<(const T_nullable& lhs, const typename T_nullable::value_type& rhs) | |||||
| { return lhs.has_value() && *lhs < rhs; } | |||||
| template<typename T_nullable> | |||||
| inline bool operator<(const typename T_nullable::value_type& lhs, const T_nullable& rhs) | |||||
| { return rhs.has_value() && lhs < *rhs; } | |||||
| template<typename T_nullable> | |||||
| inline bool operator<(const T_nullable& lhs, const T_nullable& rhs) | |||||
| { return lhs.has_value() && rhs.has_value() && *lhs < *rhs; } | |||||
| /* operator> */ | |||||
| template<typename T_nullable> | |||||
| inline bool operator>(const T_nullable& lhs, const typename T_nullable::value_type& rhs) | |||||
| { return lhs.has_value() && *lhs > rhs; } | |||||
| template<typename T_nullable> | |||||
| inline bool operator>(const typename T_nullable::value_type& lhs, const T_nullable& rhs) | |||||
| { return rhs.has_value() && lhs > *rhs; } | |||||
| template<typename T_nullable> | |||||
| inline bool operator>(const T_nullable& lhs, const T_nullable& rhs) | |||||
| { return lhs.has_value() && rhs.has_value() && *lhs > *rhs; } | |||||
| /* operator<= */ | |||||
| template<typename T_nullable> | |||||
| inline bool operator<=(const T_nullable& lhs, const typename T_nullable::value_type& rhs) | |||||
| { return lhs.has_value() && *lhs <= rhs; } | |||||
| template<typename T_nullable> | |||||
| inline bool operator<=(const typename T_nullable::value_type& lhs, const T_nullable& rhs) | |||||
| { return rhs.has_value() && lhs <= *rhs; } | |||||
| template<typename T_nullable> | |||||
| inline bool operator<=(const T_nullable& lhs, const T_nullable& rhs) | |||||
| { return lhs.has_value() && rhs.has_value() && *lhs <= *rhs; } | |||||
| /* operator>= */ | |||||
| template<typename T_nullable> | |||||
| inline bool operator>=(const T_nullable& lhs, const typename T_nullable::value_type& rhs) | |||||
| { return lhs.has_value() && *lhs >= rhs; } | |||||
| template<typename T_nullable> | |||||
| inline bool operator>=(const typename T_nullable::value_type& lhs, const T_nullable& rhs) | |||||
| { return rhs.has_value() && lhs >= *rhs; } | |||||
| template<typename T_nullable> | |||||
| inline bool operator>=(const T_nullable& lhs, const T_nullable& rhs) | |||||
| { return lhs.has_value() && rhs.has_value() && *lhs >= *rhs; } | |||||
| } | |||||
| @@ -9,7 +9,7 @@ namespace cppcore | |||||
| inline size_t bit_count(uint32_t u); | inline size_t bit_count(uint32_t u); | ||||
| /** | /** | ||||
| * @breif Try to dynamic cast the passed value to the given type. | |||||
| * @brief Try to dynamic cast the passed value to the given type. | |||||
| * | * | ||||
| * @tparam T Type to cast. | * @tparam T Type to cast. | ||||
| * @tparam S Type to cast to. | * @tparam S Type to cast to. | ||||
| @@ -1,3 +1,3 @@ | |||||
| #pragma once | #pragma once | ||||
| #include <cppcore/threading/cancellation_token.h> | |||||
| #include "threading/cancellation_token.h" | |||||
| @@ -0,0 +1,269 @@ | |||||
| #include <gtest/gtest.h> | |||||
| #include <cppcore/misc/nullable.h> | |||||
| struct TestData | |||||
| { | |||||
| static int ctorCount; | |||||
| static int dtorCount; | |||||
| TestData() | |||||
| { ++ctorCount; } | |||||
| ~TestData() | |||||
| { ++dtorCount; } | |||||
| }; | |||||
| struct NonCopyableTestData | |||||
| { | |||||
| int value; | |||||
| NonCopyableTestData(int v) : | |||||
| value(v) | |||||
| { } | |||||
| NonCopyableTestData(NonCopyableTestData&& other) : | |||||
| value(0) | |||||
| { std::swap(value, other.value); } | |||||
| NonCopyableTestData(const NonCopyableTestData&) = delete; | |||||
| }; | |||||
| using NullableInt = ::cppcore::nullable<int>; | |||||
| using NullableIntRef = ::cppcore::nullable<int&>; | |||||
| using NullableString = ::cppcore::nullable<std::string>; | |||||
| using NullableTestData = ::cppcore::nullable<TestData>; | |||||
| using NullableNonCopyableTestData = ::cppcore::nullable<NonCopyableTestData>; | |||||
| int TestData::ctorCount = 0; | |||||
| int TestData::dtorCount = 0; | |||||
| using namespace ::cppcore; | |||||
| using namespace ::testing; | |||||
| TEST(nullable_tests, ctor_empty) | |||||
| { | |||||
| NullableInt n1; | |||||
| NullableIntRef n2; | |||||
| EXPECT_FALSE(static_cast<bool>(n1)); | |||||
| EXPECT_FALSE(static_cast<bool>(n2)); | |||||
| } | |||||
| TEST(nullable_tests, ctor_value) | |||||
| { | |||||
| int i = 5; | |||||
| NullableInt n1(i); | |||||
| NullableIntRef n2(i); | |||||
| EXPECT_TRUE(static_cast<bool>(n1)); | |||||
| EXPECT_TRUE(static_cast<bool>(n2)); | |||||
| EXPECT_EQ (5, n1()); | |||||
| EXPECT_EQ (&i, &n2()); | |||||
| } | |||||
| TEST(nullable_tests, ctor_copy) | |||||
| { | |||||
| int i = 5; | |||||
| NullableInt i1(i); | |||||
| NullableIntRef i2(i); | |||||
| NullableInt n1(i1); | |||||
| NullableIntRef n2(i2); | |||||
| EXPECT_TRUE(static_cast<bool>(n1)); | |||||
| EXPECT_TRUE(static_cast<bool>(n2)); | |||||
| EXPECT_EQ (5, n1()); | |||||
| EXPECT_EQ (&i, &n2()); | |||||
| } | |||||
| TEST(nullable_tests, ctor_move) | |||||
| { | |||||
| NullableString i1("test"); | |||||
| NullableString n1(std::move(i1)); | |||||
| EXPECT_FALSE(static_cast<bool>(i1)); | |||||
| ASSERT_TRUE (static_cast<bool>(n1)); | |||||
| EXPECT_EQ (std::string("test"), n1()); | |||||
| } | |||||
| TEST(nullable_tests, move_assignment) | |||||
| { | |||||
| NullableString i1("test"); | |||||
| NullableString n1; | |||||
| n1 = std::move(i1); | |||||
| EXPECT_FALSE(static_cast<bool>(i1)); | |||||
| ASSERT_TRUE (static_cast<bool>(n1)); | |||||
| EXPECT_EQ (std::string("test"), n1()); | |||||
| } | |||||
| TEST(nullable_tests, movable_object) | |||||
| { | |||||
| NonCopyableTestData data(5); | |||||
| NullableNonCopyableTestData tmp; | |||||
| tmp = std::move(data); | |||||
| ASSERT_TRUE ( tmp.has_value() ); | |||||
| ASSERT_EQ ( 5, tmp.value().value ); | |||||
| ASSERT_EQ ( 0, data.value ); | |||||
| } | |||||
| TEST(nullable_tests, hasValue_operatorBool) | |||||
| { | |||||
| EXPECT_FALSE(static_cast<bool>(NullableInt())); | |||||
| EXPECT_FALSE(NullableInt().has_value()); | |||||
| EXPECT_TRUE (static_cast<bool>(NullableInt(5))); | |||||
| EXPECT_TRUE (NullableInt(5).has_value()); | |||||
| } | |||||
| TEST(nullable_tests, reset) | |||||
| { | |||||
| NullableTestData n(TestData{}); | |||||
| EXPECT_TRUE (n.has_value()); | |||||
| int tmp = TestData::dtorCount; | |||||
| n.reset(); | |||||
| EXPECT_FALSE(n.has_value()); | |||||
| EXPECT_EQ (tmp + 1, TestData::dtorCount); | |||||
| } | |||||
| TEST(nullable_tests, value_functor) | |||||
| { | |||||
| NullableInt n1(5); | |||||
| NullableInt n2; | |||||
| EXPECT_EQ (5, n1()); | |||||
| EXPECT_EQ (5, n1.value()); | |||||
| EXPECT_ANY_THROW(n2()); | |||||
| EXPECT_ANY_THROW(n2.value()); | |||||
| } | |||||
| TEST(nullable_tests, equalityCompareOperator) | |||||
| { | |||||
| NullableInt n1(5); | |||||
| NullableInt n2(7); | |||||
| NullableInt n3; | |||||
| EXPECT_FALSE(n2 == n1); | |||||
| EXPECT_TRUE ( 5 == n1); | |||||
| EXPECT_FALSE(n3 == n1); | |||||
| EXPECT_FALSE(n1 == n2); | |||||
| EXPECT_FALSE( 5 == n2); | |||||
| EXPECT_FALSE(n3 == n2); | |||||
| EXPECT_TRUE (n1 == 5); | |||||
| EXPECT_FALSE(n2 == 5); | |||||
| EXPECT_FALSE(n3 == 5); | |||||
| EXPECT_FALSE(n1 == n3); | |||||
| EXPECT_FALSE(n2 == n3); | |||||
| EXPECT_FALSE( 5 == n3); | |||||
| } | |||||
| TEST(nullable_tests, unequalityCompareOperator) | |||||
| { | |||||
| NullableInt n1(5); | |||||
| NullableInt n2(7); | |||||
| NullableInt n3; | |||||
| EXPECT_TRUE (n2 != n1); | |||||
| EXPECT_FALSE( 5 != n1); | |||||
| EXPECT_FALSE(n3 != n1); | |||||
| EXPECT_TRUE (n1 != n2); | |||||
| EXPECT_TRUE ( 5 != n2); | |||||
| EXPECT_FALSE(n3 != n2); | |||||
| EXPECT_FALSE(n1 != 5); | |||||
| EXPECT_TRUE (n2 != 5); | |||||
| EXPECT_FALSE(n3 != 5); | |||||
| EXPECT_FALSE(n1 != n3); | |||||
| EXPECT_FALSE(n2 != n3); | |||||
| EXPECT_FALSE( 5 != n3); | |||||
| } | |||||
| TEST(nullable_tests, lessCompareOperator) | |||||
| { | |||||
| NullableInt n1(5); | |||||
| NullableInt n2(7); | |||||
| NullableInt n3; | |||||
| EXPECT_FALSE(n2 < n1); | |||||
| EXPECT_FALSE( 5 < n1); | |||||
| EXPECT_FALSE(n3 < n1); | |||||
| EXPECT_TRUE (n1 < n2); | |||||
| EXPECT_TRUE ( 5 < n2); | |||||
| EXPECT_FALSE(n3 < n2); | |||||
| EXPECT_FALSE(n1 < 5); | |||||
| EXPECT_FALSE(n2 < 5); | |||||
| EXPECT_FALSE(n3 < 5); | |||||
| EXPECT_FALSE(n1 < n3); | |||||
| EXPECT_FALSE(n2 < n3); | |||||
| EXPECT_FALSE( 5 < n3); | |||||
| } | |||||
| TEST(nullable_tests, lessEqualCompareOperator) | |||||
| { | |||||
| NullableInt n1(5); | |||||
| NullableInt n2(7); | |||||
| NullableInt n3; | |||||
| EXPECT_FALSE(n2 <= n1); | |||||
| EXPECT_TRUE ( 5 <= n1); | |||||
| EXPECT_FALSE(n3 <= n1); | |||||
| EXPECT_TRUE (n1 <= n2); | |||||
| EXPECT_TRUE ( 5 <= n2); | |||||
| EXPECT_FALSE(n3 <= n2); | |||||
| EXPECT_TRUE (n1 <= 5); | |||||
| EXPECT_FALSE(n2 <= 5); | |||||
| EXPECT_FALSE(n3 <= 5); | |||||
| EXPECT_FALSE(n1 <= n3); | |||||
| EXPECT_FALSE(n2 <= n3); | |||||
| EXPECT_FALSE( 5 <= n3); | |||||
| } | |||||
| TEST(nullable_tests, greaterCompareOperator) | |||||
| { | |||||
| NullableInt n1(5); | |||||
| NullableInt n2(7); | |||||
| NullableInt n3; | |||||
| EXPECT_TRUE (n2 > n1); | |||||
| EXPECT_FALSE( 5 > n1); | |||||
| EXPECT_FALSE(n3 > n1); | |||||
| EXPECT_FALSE(n1 > n2); | |||||
| EXPECT_FALSE( 5 > n2); | |||||
| EXPECT_FALSE(n3 > n2); | |||||
| EXPECT_FALSE(n1 > 5); | |||||
| EXPECT_TRUE (n2 > 5); | |||||
| EXPECT_FALSE(n3 > 5); | |||||
| EXPECT_FALSE(n1 > n3); | |||||
| EXPECT_FALSE(n2 > n3); | |||||
| EXPECT_FALSE( 5 > n3); | |||||
| } | |||||
| TEST(nullable_tests, greaterEqualCompareOperator) | |||||
| { | |||||
| NullableInt n1(5); | |||||
| NullableInt n2(7); | |||||
| NullableInt n3; | |||||
| EXPECT_TRUE (n2 >= n1); | |||||
| EXPECT_TRUE ( 5 >= n1); | |||||
| EXPECT_FALSE(n3 >= n1); | |||||
| EXPECT_FALSE(n1 >= n2); | |||||
| EXPECT_FALSE( 5 >= n2); | |||||
| EXPECT_FALSE(n3 >= n2); | |||||
| EXPECT_TRUE (n1 >= 5); | |||||
| EXPECT_TRUE (n2 >= 5); | |||||
| EXPECT_FALSE(n3 >= 5); | |||||
| EXPECT_FALSE(n1 >= n3); | |||||
| EXPECT_FALSE(n2 >= n3); | |||||
| EXPECT_FALSE( 5 >= n3); | |||||
| } | |||||