From b7f5d7565a19efbfebd72f2877444c552e4230c8 Mon Sep 17 00:00:00 2001 From: Aqua-sama Date: Fri, 12 Mar 2021 16:44:02 +0200 Subject: libk: add Result class --- libk/makefile | 3 ++- libk/result.h | 23 +++++++++++++++++++++ libk/string/test.cc | 14 ------------- libk/test/result.cc | 16 +++++++++++++++ libk/test/string.cc | 14 +++++++++++++ libk/test/types.cc | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++ libk/types.h | 6 +++++- libk/types/test.cc | 51 ---------------------------------------------- 8 files changed, 118 insertions(+), 67 deletions(-) create mode 100644 libk/result.h delete mode 100644 libk/string/test.cc create mode 100644 libk/test/result.cc create mode 100644 libk/test/string.cc create mode 100644 libk/test/types.cc delete mode 100644 libk/types/test.cc diff --git a/libk/makefile b/libk/makefile index 966caae..afea066 100644 --- a/libk/makefile +++ b/libk/makefile @@ -1,4 +1,5 @@ CXX_OBJ += libk/string/string.o libk/string/integerview.o \ libk/stdlib/abort.o libk/stdlib/console.o -CXX_TEST_OBJ += libk/types/test.o libk/string/test.o + +CXX_TEST_OBJ += libk/test/types.o libk/test/string.o libk/test/result.o diff --git a/libk/result.h b/libk/result.h new file mode 100644 index 0000000..8077baf --- /dev/null +++ b/libk/result.h @@ -0,0 +1,23 @@ +#pragma once +#include + +// TODO T&& constructor +// TODO T&& Result::take() with consumed semantics + +template +class Result { +public: + explicit constexpr Result(T t) : is_ok(true), data{.t = t} {}; + explicit constexpr Result(E e) : is_ok(false), data{.e = e} {}; + + constexpr operator bool() const { return is_ok; } + constexpr E error() const { return is_ok ? E::NoError : data.e; } + constexpr T value() const { return is_ok ? data.t : T{}; } + +private: + const bool is_ok; + union { + T t; + E e; + } data; +}; diff --git a/libk/string/test.cc b/libk/string/test.cc deleted file mode 100644 index 4d7d340..0000000 --- a/libk/string/test.cc +++ /dev/null @@ -1,14 +0,0 @@ -#include - -// strlen -static_assert(strlen("") == 0); -static_assert(strlen("0") == 1); -static_assert(strlen("hello") == 5); -static_assert(strlen("world") == 5); - -// reverse -static_assert([]() { - char s[] = "xyz"; - reverse(s, strlen(s)); - return s[0] == 'z' && s[1] == 'y' && s[2] == 'x' && s[3] == '\0'; -}()); diff --git a/libk/test/result.cc b/libk/test/result.cc new file mode 100644 index 0000000..be93a07 --- /dev/null +++ b/libk/test/result.cc @@ -0,0 +1,16 @@ +#include + +enum ErrorX { one, two = 5, three, NoError }; + +// operator bool +static_assert(!(Result{ErrorX::one})); +static_assert(!(Result{ErrorX::two})); +static_assert((Result{5})); + +// error +static_assert((Result{ErrorX::one}).error() == ErrorX::one); +static_assert((Result{5}).error() == ErrorX::NoError); + +// value +static_assert((Result{ErrorX::one}).value() == int{}); +static_assert((Result{5}).value() == 5); diff --git a/libk/test/string.cc b/libk/test/string.cc new file mode 100644 index 0000000..4d7d340 --- /dev/null +++ b/libk/test/string.cc @@ -0,0 +1,14 @@ +#include + +// strlen +static_assert(strlen("") == 0); +static_assert(strlen("0") == 1); +static_assert(strlen("hello") == 5); +static_assert(strlen("world") == 5); + +// reverse +static_assert([]() { + char s[] = "xyz"; + reverse(s, strlen(s)); + return s[0] == 'z' && s[1] == 'y' && s[2] == 'x' && s[3] == '\0'; +}()); diff --git a/libk/test/types.cc b/libk/test/types.cc new file mode 100644 index 0000000..3686a78 --- /dev/null +++ b/libk/test/types.cc @@ -0,0 +1,58 @@ +#include + +namespace libk { +#include "types.h" +} + +// types +static_assert(sizeof(libk::size_t) >= 2); + +static_assert(sizeof(libk::uint8_t) == 1); +static_assert(libk::uint8_t_max == UINT8_MAX); + +static_assert(sizeof(libk::uint16_t) == 2); +static_assert(libk::uint16_t_max == UINT16_MAX); + +static_assert(sizeof(libk::uint32_t) == 4); +static_assert(libk::uint32_t_max == UINT32_MAX); + +static_assert(sizeof(libk::uint64_t) == 8); +static_assert(libk::uint64_t_max == UINT64_MAX); + +static_assert(sizeof(libk::int8_t) == 1); +static_assert(libk::int8_t_min == INT8_MIN); +static_assert(libk::int8_t_max == INT8_MAX); + +static_assert(sizeof(libk::int16_t) == 2); +static_assert(libk::int16_t_min == INT16_MIN); +static_assert(libk::int16_t_max == INT16_MAX); + +static_assert(sizeof(libk::int32_t) == 4); +static_assert(libk::int32_t_min == INT32_MIN); +static_assert(libk::int32_t_max == INT32_MAX); + +static_assert(sizeof(libk::int64_t) == 8); +static_assert(libk::int64_t_min == INT64_MIN); +static_assert(libk::int64_t_max == INT64_MAX); + +// is_same +static_assert(libk::is_same() == true); +static_assert(libk::is_same() == false); + +// is_unsigned +static_assert(libk::is_unsigned() == true); +static_assert(libk::is_unsigned() == true); +static_assert(libk::is_unsigned() == true); +static_assert(libk::is_unsigned() == true); + +static_assert(libk::is_unsigned() == false); +static_assert(libk::is_unsigned() == false); +static_assert(libk::is_unsigned() == false); +static_assert(libk::is_unsigned() == false); + +// error_enum_t +enum EnumX { x, y, z }; +enum ErrorX { one, two, three, NoError }; + +static_assert(!libk::error_enum_t); +static_assert(libk::error_enum_t); diff --git a/libk/types.h b/libk/types.h index 7f16206..3e728fb 100644 --- a/libk/types.h +++ b/libk/types.h @@ -35,7 +35,7 @@ typedef long long int int64_t; constexpr int64_t int64_t_max = uint64_t_max / 2; constexpr int64_t int64_t_min = -int64_t_max - 1; -// Type Traits +/* Type Traits */ template struct integral_constant { @@ -54,3 +54,7 @@ struct is_same : integral_constant {}; /* is_unsigned */ template struct is_unsigned : integral_constant(-1))> {}; + +/* error enum concept */ +template +concept error_enum_t = (__is_enum(T) && requires { T::NoError; }); diff --git a/libk/types/test.cc b/libk/types/test.cc deleted file mode 100644 index b3f29d9..0000000 --- a/libk/types/test.cc +++ /dev/null @@ -1,51 +0,0 @@ -#include - -namespace libk { -#include "types.h" -} - -// types -static_assert(sizeof(libk::size_t) >= 2); - -static_assert(sizeof(libk::uint8_t) == 1); -static_assert(libk::uint8_t_max == UINT8_MAX); - -static_assert(sizeof(libk::uint16_t) == 2); -static_assert(libk::uint16_t_max == UINT16_MAX); - -static_assert(sizeof(libk::uint32_t) == 4); -static_assert(libk::uint32_t_max == UINT32_MAX); - -static_assert(sizeof(libk::uint64_t) == 8); -static_assert(libk::uint64_t_max == UINT64_MAX); - -static_assert(sizeof(libk::int8_t) == 1); -static_assert(libk::int8_t_min == INT8_MIN); -static_assert(libk::int8_t_max == INT8_MAX); - -static_assert(sizeof(libk::int16_t) == 2); -static_assert(libk::int16_t_min == INT16_MIN); -static_assert(libk::int16_t_max == INT16_MAX); - -static_assert(sizeof(libk::int32_t) == 4); -static_assert(libk::int32_t_min == INT32_MIN); -static_assert(libk::int32_t_max == INT32_MAX); - -static_assert(sizeof(libk::int64_t) == 8); -static_assert(libk::int64_t_min == INT64_MIN); -static_assert(libk::int64_t_max == INT64_MAX); - -// is_same -static_assert(libk::is_same() == true); -static_assert(libk::is_same() == false); - -// is_unsigned -static_assert(libk::is_unsigned() == true); -static_assert(libk::is_unsigned() == true); -static_assert(libk::is_unsigned() == true); -static_assert(libk::is_unsigned() == true); - -static_assert(libk::is_unsigned() == false); -static_assert(libk::is_unsigned() == false); -static_assert(libk::is_unsigned() == false); -static_assert(libk::is_unsigned() == false); -- cgit v1.2.1