From 8526ae1d91229c7d1eff0f62725f0d6cb9157871 Mon Sep 17 00:00:00 2001 From: Andreas Tsouchlos Date: Fri, 18 Feb 2022 23:31:15 +0100 Subject: [PATCH 01/16] First version of std::array --- const_fmt/std_lib.h | 71 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 const_fmt/std_lib.h diff --git a/const_fmt/std_lib.h b/const_fmt/std_lib.h new file mode 100644 index 0000000..6432bed --- /dev/null +++ b/const_fmt/std_lib.h @@ -0,0 +1,71 @@ +#ifndef CONST_FMT_STD_LIB_H +#define CONST_FMT_STD_LIB_H + + +#ifdef CONST_FMT_NO_STD_LIB + + +#include + + +namespace std { + + +using size_t = uint16_t; + + +// TODO: Is std::size_t really the best bet here? +template +class array { +public: + // Constructors + + array() = default; + array(const array& other) = default; + array(array&& other) = default; + + // Operators + + array operator=(const array& other) = default; + array operator=(array&& other) = default; + + // Element access + + data_t& operator[](std::size_t index) { + return m_data[index]; + } + const data_t& operator[](std::size_t index) const { + return m_data[index]; + } + + // Iterators + + using iterator = data_t*; + using const_iterator = const data_t*; + + iterator begin() { + return &(m_data[0]); + } + iterator end() { + return (&(m_data[t_size-1]) + 1); + } + + const iterator cbegin() const { + return &(m_data[0]); + } + const iterator cend() const { + return (&(m_data[t_size-1]) + 1); + } + +private: + data_t m_data[t_size]; +}; + + +} // namespace std + + +#endif + + +#endif // CONST_FMT_STD_LIB_H -- 2.45.2 From 8f7b1cd4e3809b0feb721f1c9bed67be2a1ca541 Mon Sep 17 00:00:00 2001 From: Andreas Tsouchlos Date: Sun, 20 Feb 2022 00:14:33 +0100 Subject: [PATCH 02/16] Implemented std::array and a bunch of other stuff --- const_fmt/std_lib.h | 92 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 74 insertions(+), 18 deletions(-) diff --git a/const_fmt/std_lib.h b/const_fmt/std_lib.h index 6432bed..305e066 100644 --- a/const_fmt/std_lib.h +++ b/const_fmt/std_lib.h @@ -2,10 +2,14 @@ #define CONST_FMT_STD_LIB_H -#ifdef CONST_FMT_NO_STD_LIB +#ifndef CONST_FMT_NO_CPP_STD_LIB +#include + +#else #include +#include namespace std { @@ -14,47 +18,99 @@ namespace std { using size_t = uint16_t; +/* + * + * type_traits + * + */ + + +// clang-format off + +template struct remove_reference { using type = T; }; +template struct remove_reference { using type = T; }; +template struct remove_reference { using type = T; }; + +template +using remove_reference_t = typename std::remove_reference::type; + +// clang-format on + + +/* + * + * utility + * + */ + + +template +std::remove_reference_t&& move(T&& arg) noexcept { + return reinterpret_cast&&>(arg); +} + +template +void swap(T& t1, T& t2) { + T temp = std::move(t1); + t1 = std::move(t2); + t2 = std::move(temp); +} + + +/* + * + * std::array + * + */ + + // TODO: Is std::size_t really the best bet here? template class array { public: - // Constructors + template + constexpr array(args_t... args) noexcept : m_data{args...} { + static_assert(sizeof...(args) == t_size, "Invalid number of arguments"); + } - array() = default; - array(const array& other) = default; - array(array&& other) = default; + constexpr array() noexcept = default; + constexpr array(array&) = default; + constexpr array(array&&) = default; - // Operators + constexpr array& operator=(array& other) = default; + constexpr array& operator=(array&& other) = default; - array operator=(const array& other) = default; - array operator=(array&& other) = default; + constexpr void swap(array& other) noexcept { + for (int i = 0; i < t_size; ++i) { + using std::swap; + swap(m_data[i], other.m_data[i]); + } + } - // Element access - data_t& operator[](std::size_t index) { + constexpr data_t& operator[](std::size_t index) noexcept { return m_data[index]; } - const data_t& operator[](std::size_t index) const { + constexpr const data_t& operator[](std::size_t index) const noexcept { return m_data[index]; } - // Iterators using iterator = data_t*; using const_iterator = const data_t*; - iterator begin() { + constexpr iterator begin() noexcept { return &(m_data[0]); } - iterator end() { - return (&(m_data[t_size-1]) + 1); + constexpr iterator end() noexcept { + return (&(m_data[t_size - 1]) + 1); } - const iterator cbegin() const { + constexpr const_iterator cbegin() const noexcept { return &(m_data[0]); } - const iterator cend() const { - return (&(m_data[t_size-1]) + 1); + constexpr const_iterator cend() const noexcept { + return (&(m_data[t_size - 1]) + 1); } private: -- 2.45.2 From 6ba83fd582e2ac61ab3e8acdc62eb38ccbe4920f Mon Sep 17 00:00:00 2001 From: Andreas Tsouchlos Date: Sun, 20 Feb 2022 00:15:31 +0100 Subject: [PATCH 03/16] Minor changes to make sure some stuff works with no stl headers --- const_fmt/types.h | 7 ++++--- const_fmt/utility.h | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/const_fmt/types.h b/const_fmt/types.h index 071937a..688e4b8 100644 --- a/const_fmt/types.h +++ b/const_fmt/types.h @@ -2,7 +2,8 @@ #define LOGGER_TYPES_H -#include + +#include "std_lib.h" namespace const_fmt { namespace const_fmt_detail { @@ -19,8 +20,8 @@ template class ConstString { public: constexpr ConstString(const char (&content)[N]) noexcept { - std::copy(std::begin(content), std::end(content), - std::begin(m_content)); + std::copy(&content[0], (&content[N-1] + 1), + m_content.begin()); } constexpr char operator[](std::size_t index) const noexcept { diff --git a/const_fmt/utility.h b/const_fmt/utility.h index e87a664..3a261c5 100644 --- a/const_fmt/utility.h +++ b/const_fmt/utility.h @@ -2,8 +2,9 @@ #define LOGGER_UTILITY_H -#include +#include +#include "std_lib.h" #include "types.h" -- 2.45.2 From 9bd1104e5fd44cb25ebab81f663a9166970a0b70 Mon Sep 17 00:00:00 2001 From: Andreas Tsouchlos Date: Sun, 20 Feb 2022 00:26:48 +0100 Subject: [PATCH 04/16] Code compiles and passes tests without NO_STDLIB define --- const_fmt/format_impl.h | 1 + const_fmt/std_lib.h | 1 + const_fmt/types.h | 3 +-- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/const_fmt/format_impl.h b/const_fmt/format_impl.h index 73748f9..a561668 100644 --- a/const_fmt/format_impl.h +++ b/const_fmt/format_impl.h @@ -12,6 +12,7 @@ #include +#include "std_lib.h" #include "utility.h" diff --git a/const_fmt/std_lib.h b/const_fmt/std_lib.h index 305e066..4fb5820 100644 --- a/const_fmt/std_lib.h +++ b/const_fmt/std_lib.h @@ -5,6 +5,7 @@ #ifndef CONST_FMT_NO_CPP_STD_LIB #include +#include #else diff --git a/const_fmt/types.h b/const_fmt/types.h index 688e4b8..dcf1990 100644 --- a/const_fmt/types.h +++ b/const_fmt/types.h @@ -20,8 +20,7 @@ template class ConstString { public: constexpr ConstString(const char (&content)[N]) noexcept { - std::copy(&content[0], (&content[N-1] + 1), - m_content.begin()); + std::copy(&content[0], (&content[N - 1] + 1), m_content.begin()); } constexpr char operator[](std::size_t index) const noexcept { -- 2.45.2 From 8e51facd10da43c85e1383465336c23160e7b07d Mon Sep 17 00:00:00 2001 From: Andreas Tsouchlos Date: Sun, 20 Feb 2022 00:27:45 +0100 Subject: [PATCH 05/16] fixed wrong clang-format comments --- const_fmt/parse.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/const_fmt/parse.h b/const_fmt/parse.h index f8260c5..e5350b6 100644 --- a/const_fmt/parse.h +++ b/const_fmt/parse.h @@ -5,7 +5,7 @@ #include "types.h" -// clang-const_format off +// clang-format off /* * @@ -34,7 +34,7 @@ * */ -// clang-const_format on +// clang-format on namespace const_fmt { namespace const_fmt_detail { -- 2.45.2 From 5ba17232951ccf53660b519eeadf70116132c185 Mon Sep 17 00:00:00 2001 From: Andreas Tsouchlos Date: Sun, 20 Feb 2022 14:29:58 +0100 Subject: [PATCH 06/16] Made array a structural type --- const_fmt/std_lib.h | 1 - 1 file changed, 1 deletion(-) diff --git a/const_fmt/std_lib.h b/const_fmt/std_lib.h index 4fb5820..735e2c3 100644 --- a/const_fmt/std_lib.h +++ b/const_fmt/std_lib.h @@ -114,7 +114,6 @@ public: return (&(m_data[t_size - 1]) + 1); } -private: data_t m_data[t_size]; }; -- 2.45.2 From ea722ec5bf6639524d9a268bb58ceaaac7c102b6 Mon Sep 17 00:00:00 2001 From: Andreas Tsouchlos Date: Wed, 23 Feb 2022 19:45:17 +0100 Subject: [PATCH 07/16] Changed includes; Implemented std::pair and std::make_unsigned; changed usage of std::memcpy to memcpy --- const_fmt/format.h | 2 +- const_fmt/format_impl.h | 4 +- const_fmt/std_lib.h | 127 ----------------------- const_fmt/stdlib.h | 209 ++++++++++++++++++++++++++++++++++++++ const_fmt/types.h | 2 +- const_fmt/utility.h | 2 +- examples/src/examples.cpp | 12 ++- 7 files changed, 221 insertions(+), 137 deletions(-) delete mode 100644 const_fmt/std_lib.h create mode 100644 const_fmt/stdlib.h diff --git a/const_fmt/format.h b/const_fmt/format.h index 994d8e0..ee42bb5 100644 --- a/const_fmt/format.h +++ b/const_fmt/format.h @@ -57,7 +57,7 @@ constexpr inline void format_arg(char* dest, const char* arg) { dest = dest + fmt_data.length - len; if (!std::is_constant_evaluated()) { - std::memcpy(dest, arg, len); + memcpy(dest, arg, len); return; } for (std::size_t i = 0; i < len; ++i) { diff --git a/const_fmt/format_impl.h b/const_fmt/format_impl.h index a561668..afad960 100644 --- a/const_fmt/format_impl.h +++ b/const_fmt/format_impl.h @@ -12,7 +12,7 @@ #include -#include "std_lib.h" +#include "stdlib.h" #include "utility.h" @@ -120,7 +120,7 @@ constexpr inline const char* digits2_base(size_t value) { constexpr inline void copy2(char* dst, const char* src) { if (!std::is_constant_evaluated()) { - std::memcpy(dst, src, 2); + memcpy(dst, src, 2); return; } *dst++ = static_cast(*src++); diff --git a/const_fmt/std_lib.h b/const_fmt/std_lib.h deleted file mode 100644 index 735e2c3..0000000 --- a/const_fmt/std_lib.h +++ /dev/null @@ -1,127 +0,0 @@ -#ifndef CONST_FMT_STD_LIB_H -#define CONST_FMT_STD_LIB_H - - -#ifndef CONST_FMT_NO_CPP_STD_LIB - -#include -#include - -#else - -#include -#include - - -namespace std { - - -using size_t = uint16_t; - - -/* - * - * type_traits - * - */ - - -// clang-format off - -template struct remove_reference { using type = T; }; -template struct remove_reference { using type = T; }; -template struct remove_reference { using type = T; }; - -template -using remove_reference_t = typename std::remove_reference::type; - -// clang-format on - - -/* - * - * utility - * - */ - - -template -std::remove_reference_t&& move(T&& arg) noexcept { - return reinterpret_cast&&>(arg); -} - -template -void swap(T& t1, T& t2) { - T temp = std::move(t1); - t1 = std::move(t2); - t2 = std::move(temp); -} - - -/* - * - * std::array - * - */ - - -// TODO: Is std::size_t really the best bet here? -template -class array { -public: - template - constexpr array(args_t... args) noexcept : m_data{args...} { - static_assert(sizeof...(args) == t_size, "Invalid number of arguments"); - } - - constexpr array() noexcept = default; - constexpr array(array&) = default; - constexpr array(array&&) = default; - - constexpr array& operator=(array& other) = default; - constexpr array& operator=(array&& other) = default; - - constexpr void swap(array& other) noexcept { - for (int i = 0; i < t_size; ++i) { - using std::swap; - swap(m_data[i], other.m_data[i]); - } - } - - - constexpr data_t& operator[](std::size_t index) noexcept { - return m_data[index]; - } - constexpr const data_t& operator[](std::size_t index) const noexcept { - return m_data[index]; - } - - - using iterator = data_t*; - using const_iterator = const data_t*; - - constexpr iterator begin() noexcept { - return &(m_data[0]); - } - constexpr iterator end() noexcept { - return (&(m_data[t_size - 1]) + 1); - } - - constexpr const_iterator cbegin() const noexcept { - return &(m_data[0]); - } - constexpr const_iterator cend() const noexcept { - return (&(m_data[t_size - 1]) + 1); - } - - data_t m_data[t_size]; -}; - - -} // namespace std - - -#endif - - -#endif // CONST_FMT_STD_LIB_H diff --git a/const_fmt/stdlib.h b/const_fmt/stdlib.h new file mode 100644 index 0000000..f6f22b0 --- /dev/null +++ b/const_fmt/stdlib.h @@ -0,0 +1,209 @@ +#ifndef CONST_FMT_STDLIB_H +#define CONST_FMT_STDLIB_H + + +/* + * + * Disclaimer: Probably very bad implementation of some features of the C++ + * Standard Library. Not meant as a full-on stdlib implementation, only for + * usage in this project (Underlined by the fact, that in this case the + * namespace std is actually const_fmt::std) + * + */ + + +#ifndef CONST_FMT_NO_CPP_STDLIB + +#include +#include + +#else + +#include +#include + + +namespace const_fmt { namespace std { + + +using size_t = uint16_t; + + +/* + * + * type_traits + * + */ + + +// clang-format off + + template + struct remove_reference { + using type = T; + }; + template + struct remove_reference { + using type = T; + }; + template + struct remove_reference { + using type = T; + }; + + template + using remove_reference_t = typename std::remove_reference::type; + +// clang-format on + + +constexpr inline bool is_constant_evaluated() noexcept { + return __builtin_is_constant_evaluated(); +} + + +// clang-format off + +template struct make_unsigned { using type = type_t; }; + +template <> struct make_unsigned { using type = char; }; +template <> struct make_unsigned { using type = unsigned short; }; +template <> struct make_unsigned { using type = unsigned int; }; +template <> struct make_unsigned { using type = unsigned long; }; +template <> struct make_unsigned { using type = unsigned long long; }; + +// clang-format on + + +/* + * + * concepts + * + */ + + +//template +//concept integral = is_integral_v<_Tp>; +// +//template +//concept signed_integral = integral<_Tp> && is_signed_v<_Tp>; +// +//template +//concept unsigned_integral = integral<_Tp> && !signed_integral<_Tp>; +// +//template +//concept floating_point = is_floating_point_v<_Tp>; + + +/* + * + * algorithm + * + */ + + +template +void copy(input_t* start, input_t* end, output_t* dest_start) { + memcpy(start, dest_start, end - start); +} + + +/* + * + * utility + * + */ + + +template +std::remove_reference_t&& move(T&& arg) noexcept { + return reinterpret_cast&&>(arg); +} + +template +void swap(T& t1, T& t2) { + T temp = std::move(t1); + t1 = std::move(t2); + t2 = std::move(temp); +} + +template +struct pair { + first_t first; + second_t second; +}; + + +/* + * + * array + * + */ + + +// TODO: Is std::size_t really the best bet here? +template +class array { +public: + template + constexpr array(args_t... args) noexcept : m_data{args...} { + static_assert(sizeof...(args) == t_size, "Invalid number of arguments"); + } + + constexpr array() noexcept = default; + + constexpr array(array&) = default; + + constexpr array(array&&) = default; + + constexpr array& operator=(array& other) = default; + + constexpr array& operator=(array&& other) = default; + + constexpr void swap(array& other) noexcept { + for (int i = 0; i < t_size; ++i) { + using std::swap; + swap(m_data[i], other.m_data[i]); + } + } + + + constexpr data_t& operator[](std::size_t index) noexcept { + return m_data[index]; + } + + constexpr const data_t& operator[](std::size_t index) const noexcept { + return m_data[index]; + } + + + using iterator = data_t*; + using const_iterator = const data_t*; + + constexpr iterator begin() noexcept { + return &(m_data[0]); + } + + constexpr iterator end() noexcept { + return (&(m_data[t_size - 1]) + 1); + } + + constexpr const_iterator cbegin() const noexcept { + return &(m_data[0]); + } + + constexpr const_iterator cend() const noexcept { + return (&(m_data[t_size - 1]) + 1); + } + + data_t m_data[t_size]; +}; + + +}} // namespace const_fmt::std + + +#endif + + +#endif // CONST_FMT_STDLIB_H diff --git a/const_fmt/types.h b/const_fmt/types.h index dcf1990..a8caf66 100644 --- a/const_fmt/types.h +++ b/const_fmt/types.h @@ -3,7 +3,7 @@ -#include "std_lib.h" +#include "stdlib.h" namespace const_fmt { namespace const_fmt_detail { diff --git a/const_fmt/utility.h b/const_fmt/utility.h index 3a261c5..2e41a3d 100644 --- a/const_fmt/utility.h +++ b/const_fmt/utility.h @@ -4,7 +4,7 @@ #include -#include "std_lib.h" +#include "stdlib.h" #include "types.h" diff --git a/examples/src/examples.cpp b/examples/src/examples.cpp index e955122..14e3c4b 100644 --- a/examples/src/examples.cpp +++ b/examples/src/examples.cpp @@ -1,6 +1,8 @@ +#define CONST_FMT_NO_CPP_STDLIB + #include -#include -#include +//#include +//#include using namespace const_fmt; @@ -9,9 +11,9 @@ int main() { // Convert s (with a type of 'std::array') into something // writable to std::cout - std::string_view sv{&s[0], s.size()}; - - std::cout << sv << std::endl; +// std::string_view sv{&s[0], s.size()}; +// +// std::cout << sv << std::endl; return 0; } \ No newline at end of file -- 2.45.2 From 826f3a54b3bb1c5b372b4675cd09a796afe10691 Mon Sep 17 00:00:00 2001 From: Andreas Tsouchlos Date: Wed, 23 Feb 2022 19:46:33 +0100 Subject: [PATCH 08/16] Changed comment --- const_fmt/stdlib.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/const_fmt/stdlib.h b/const_fmt/stdlib.h index f6f22b0..79ba8a7 100644 --- a/const_fmt/stdlib.h +++ b/const_fmt/stdlib.h @@ -4,7 +4,7 @@ /* * - * Disclaimer: Probably very bad implementation of some features of the C++ + * Disclaimer: Very bad (partially at least) implementation of some features of the C++ * Standard Library. Not meant as a full-on stdlib implementation, only for * usage in this project (Underlined by the fact, that in this case the * namespace std is actually const_fmt::std) -- 2.45.2 From b5ecd73b1868aff2addb69aedca5ed86299ffa21 Mon Sep 17 00:00:00 2001 From: Andreas Tsouchlos Date: Wed, 23 Feb 2022 19:47:06 +0100 Subject: [PATCH 09/16] Formatting --- const_fmt/stdlib.h | 50 +++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/const_fmt/stdlib.h b/const_fmt/stdlib.h index 79ba8a7..c5b4e1c 100644 --- a/const_fmt/stdlib.h +++ b/const_fmt/stdlib.h @@ -4,9 +4,9 @@ /* * - * Disclaimer: Very bad (partially at least) implementation of some features of the C++ - * Standard Library. Not meant as a full-on stdlib implementation, only for - * usage in this project (Underlined by the fact, that in this case the + * Disclaimer: Very bad (partially at least) implementation of some features of + * the C++ Standard Library. Not meant as a full-on stdlib implementation, only + * for usage in this project (Underlined by the fact, that in this case the * namespace std is actually const_fmt::std) * */ @@ -38,21 +38,21 @@ using size_t = uint16_t; // clang-format off - template - struct remove_reference { - using type = T; - }; - template - struct remove_reference { - using type = T; - }; - template - struct remove_reference { - using type = T; - }; +template +struct remove_reference { + using type = T; +}; +template +struct remove_reference { + using type = T; +}; +template +struct remove_reference { + using type = T; +}; - template - using remove_reference_t = typename std::remove_reference::type; +template +using remove_reference_t = typename std::remove_reference::type; // clang-format on @@ -82,17 +82,17 @@ template <> struct make_unsigned { using type = unsigned long */ -//template -//concept integral = is_integral_v<_Tp>; +// template +// concept integral = is_integral_v<_Tp>; // -//template -//concept signed_integral = integral<_Tp> && is_signed_v<_Tp>; +// template +// concept signed_integral = integral<_Tp> && is_signed_v<_Tp>; // -//template -//concept unsigned_integral = integral<_Tp> && !signed_integral<_Tp>; +// template +// concept unsigned_integral = integral<_Tp> && !signed_integral<_Tp>; // -//template -//concept floating_point = is_floating_point_v<_Tp>; +// template +// concept floating_point = is_floating_point_v<_Tp>; /* -- 2.45.2 From 91398ef23de9f87d2bda396fc475b7924831230e Mon Sep 17 00:00:00 2001 From: Andreas Tsouchlos Date: Wed, 23 Feb 2022 19:51:55 +0100 Subject: [PATCH 10/16] Added remove_cv, remove_const and remove_volatile --- const_fmt/stdlib.h | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/const_fmt/stdlib.h b/const_fmt/stdlib.h index c5b4e1c..7c249ca 100644 --- a/const_fmt/stdlib.h +++ b/const_fmt/stdlib.h @@ -38,22 +38,25 @@ using size_t = uint16_t; // clang-format off -template -struct remove_reference { - using type = T; -}; -template -struct remove_reference { - using type = T; -}; -template -struct remove_reference { - using type = T; -}; +template struct remove_reference { using type = T; }; +template struct remove_reference {using type = T; }; +template struct remove_reference { using type = T; }; -template +template using remove_reference_t = typename std::remove_reference::type; + +template struct remove_cv { typedef T type; }; +template struct remove_cv { typedef T type; }; +template struct remove_cv { typedef T type; }; +template struct remove_cv { typedef T type; }; + +template struct remove_const { typedef T type; }; +template struct remove_const { typedef T type; }; + +template struct remove_volatile { typedef T type; }; +template struct remove_volatile { typedef T type; }; + // clang-format on -- 2.45.2 From 73a50cae0f7cf40412d33299bd40429ba815a3e5 Mon Sep 17 00:00:00 2001 From: Andreas Tsouchlos Date: Wed, 23 Feb 2022 20:42:56 +0100 Subject: [PATCH 11/16] Added is_integral and is_floating_point --- const_fmt/stdlib.h | 73 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 57 insertions(+), 16 deletions(-) diff --git a/const_fmt/stdlib.h b/const_fmt/stdlib.h index 7c249ca..5444b7a 100644 --- a/const_fmt/stdlib.h +++ b/const_fmt/stdlib.h @@ -36,28 +36,71 @@ using size_t = uint16_t; */ +struct true_type { + constexpr static bool value = true; +}; + +struct false_type { + constexpr static bool value = false; +}; + + // clang-format off -template struct remove_reference { using type = T; }; -template struct remove_reference {using type = T; }; -template struct remove_reference { using type = T; }; +template struct remove_cv { typedef type_t type; }; +template struct remove_cv { typedef type_t type; }; +template struct remove_cv { typedef type_t type; }; +template struct remove_cv { typedef type_t type; }; -template -using remove_reference_t = typename std::remove_reference::type; +template struct remove_const { typedef type_t type; }; +template struct remove_const { typedef type_t type; }; + +template struct remove_volatile { typedef type_t type; }; +template struct remove_volatile { typedef type_t type; }; + +template struct remove_reference { using type = type_t; }; +template struct remove_reference { using type = type_t; }; +template struct remove_reference { using type = type_t; }; + +template using remove_reference_t = typename std::remove_reference::type; +template using remove_cv_t = typename std::remove_cv::type; +template using remove_const_t = typename std::remove_const::type; +template using remove_volatile_t = typename std::remove_volatile::type; -template struct remove_cv { typedef T type; }; -template struct remove_cv { typedef T type; }; -template struct remove_cv { typedef T type; }; -template struct remove_cv { typedef T type; }; +template struct is_integral_helper : public false_type {}; -template struct remove_const { typedef T type; }; -template struct remove_const { typedef T type; }; +template <> struct is_integral_helper : public true_type {}; +template <> struct is_integral_helper : public true_type {}; +template <> struct is_integral_helper : public true_type {}; +template <> struct is_integral_helper : public true_type {}; +template <> struct is_integral_helper : public true_type {}; +template <> struct is_integral_helper : public true_type {}; +template <> struct is_integral_helper : public true_type {}; +template <> struct is_integral_helper : public true_type {}; +template <> struct is_integral_helper : public true_type {}; +template <> struct is_integral_helper : public true_type {}; +template <> struct is_integral_helper : public true_type {}; +template <> struct is_integral_helper : public true_type {}; +template <> struct is_integral_helper : public true_type {}; +template <> struct is_integral_helper : public true_type {}; +template <> struct is_integral_helper : public true_type {}; -template struct remove_volatile { typedef T type; }; -template struct remove_volatile { typedef T type; }; +template +struct is_integral + : public is_integral_helper> {}; + + +template struct is_floating_point_helper : public false_type {}; + +template<> struct is_floating_point_helper : public true_type {}; +template<> struct is_floating_point_helper : public true_type {}; +template<> struct is_floating_point_helper : public true_type {}; + +template +struct is_floating_point + : public is_floating_point_helper>::type {}; -// clang-format on constexpr inline bool is_constant_evaluated() noexcept { @@ -65,8 +108,6 @@ constexpr inline bool is_constant_evaluated() noexcept { } -// clang-format off - template struct make_unsigned { using type = type_t; }; template <> struct make_unsigned { using type = char; }; -- 2.45.2 From 7796be7cd402f9a29f52e511aeb3016d4c881453 Mon Sep 17 00:00:00 2001 From: Andreas Tsouchlos Date: Wed, 23 Feb 2022 23:12:34 +0100 Subject: [PATCH 12/16] Reimplemented is_integral and is_floating_point with different approach; Made functions constexpr inline --- const_fmt/stdlib.h | 90 +++++++++++++++++++++++++++++----------------- 1 file changed, 58 insertions(+), 32 deletions(-) diff --git a/const_fmt/stdlib.h b/const_fmt/stdlib.h index 5444b7a..0e46a93 100644 --- a/const_fmt/stdlib.h +++ b/const_fmt/stdlib.h @@ -36,6 +36,13 @@ using size_t = uint16_t; */ +// various + + +constexpr inline bool is_constant_evaluated() noexcept { + return __builtin_is_constant_evaluated(); +} + struct true_type { constexpr static bool value = true; }; @@ -45,6 +52,35 @@ struct false_type { }; +// is_same + + +template +struct is_same : public false_type {}; + +template +struct is_same : public false_type {}; + + +// is_one_of + + +template +struct is_one_of; +template +struct is_one_of { + constexpr static bool value = false; +}; +template +struct is_one_of { + constexpr static bool value = std::is_same::value || + is_one_of::value; +}; + + +// remove_x + + // clang-format off template struct remove_cv { typedef type_t type; }; @@ -67,46 +103,36 @@ template using remove_cv_t = typename std::remove_cv using remove_const_t = typename std::remove_const::type; template using remove_volatile_t = typename std::remove_volatile::type; +// clang-format on -template struct is_integral_helper : public false_type {}; -template <> struct is_integral_helper : public true_type {}; -template <> struct is_integral_helper : public true_type {}; -template <> struct is_integral_helper : public true_type {}; -template <> struct is_integral_helper : public true_type {}; -template <> struct is_integral_helper : public true_type {}; -template <> struct is_integral_helper : public true_type {}; -template <> struct is_integral_helper : public true_type {}; -template <> struct is_integral_helper : public true_type {}; -template <> struct is_integral_helper : public true_type {}; -template <> struct is_integral_helper : public true_type {}; -template <> struct is_integral_helper : public true_type {}; -template <> struct is_integral_helper : public true_type {}; -template <> struct is_integral_helper : public true_type {}; -template <> struct is_integral_helper : public true_type {}; -template <> struct is_integral_helper : public true_type {}; +// is_integral + template -struct is_integral - : public is_integral_helper> {}; +struct is_integral { + constexpr static bool value = + is_one_of, bool, char, signed char, unsigned char, + wchar_t, char16_t, char32_t, short, unsigned short, int, + unsigned int, long, unsigned long, long long, + unsigned long long>::value; +}; -template struct is_floating_point_helper : public false_type {}; - -template<> struct is_floating_point_helper : public true_type {}; -template<> struct is_floating_point_helper : public true_type {}; -template<> struct is_floating_point_helper : public true_type {}; - -template -struct is_floating_point - : public is_floating_point_helper>::type {}; +// is_floating_point +template +struct is_floating_point { + constexpr static bool value = + is_one_of, float, double, long double>::value; +}; -constexpr inline bool is_constant_evaluated() noexcept { - return __builtin_is_constant_evaluated(); -} +// make_unsigned + + +// clang-format off template struct make_unsigned { using type = type_t; }; @@ -147,7 +173,7 @@ template <> struct make_unsigned { using type = unsigned long template -void copy(input_t* start, input_t* end, output_t* dest_start) { +constexpr inline void copy(input_t* start, input_t* end, output_t* dest_start) { memcpy(start, dest_start, end - start); } @@ -165,7 +191,7 @@ std::remove_reference_t&& move(T&& arg) noexcept { } template -void swap(T& t1, T& t2) { +constexpr inline void swap(T& t1, T& t2) { T temp = std::move(t1); t1 = std::move(t2); t2 = std::move(temp); -- 2.45.2 From 86930fd8b0fd93e8def5f85c446de84b9e8db483 Mon Sep 17 00:00:00 2001 From: Andreas Tsouchlos Date: Thu, 24 Feb 2022 16:14:38 +0100 Subject: [PATCH 13/16] Added conepts; Fixed bug in const_fmt::std::true_type --- const_fmt/stdlib.h | 60 ++++++++++++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 23 deletions(-) diff --git a/const_fmt/stdlib.h b/const_fmt/stdlib.h index 0e46a93..b963489 100644 --- a/const_fmt/stdlib.h +++ b/const_fmt/stdlib.h @@ -59,7 +59,7 @@ template struct is_same : public false_type {}; template -struct is_same : public false_type {}; +struct is_same : public true_type {}; // is_one_of @@ -110,23 +110,27 @@ template using remove_volatile_t = typename std::remove_volat template -struct is_integral { - constexpr static bool value = - is_one_of, bool, char, signed char, unsigned char, - wchar_t, char16_t, char32_t, short, unsigned short, int, - unsigned int, long, unsigned long, long long, - unsigned long long>::value; -}; +using is_integral = + is_one_of, bool, char, signed char, unsigned char, + wchar_t, char16_t, char32_t, short, unsigned short, int, + unsigned int, long, unsigned long, long long, unsigned long long>; + + +// is_signed + + +template +using is_signed_integer = is_one_of, signed char, signed short, + signed int, signed long, signed long long>; + // is_floating_point template -struct is_floating_point { - constexpr static bool value = - is_one_of, float, double, long double>::value; -}; +using is_floating_point = + is_one_of, float, double, long double>; // make_unsigned @@ -145,6 +149,16 @@ template <> struct make_unsigned { using type = unsigned long // clang-format on +// value definitions + +template +inline constexpr bool is_integral_v = is_integral::value; +template +inline constexpr bool is_signed_integer_v = is_signed_integer::value; +template +inline constexpr bool is_floating_point_v = is_floating_point::value; + + /* * * concepts @@ -152,17 +166,17 @@ template <> struct make_unsigned { using type = unsigned long */ -// template -// concept integral = is_integral_v<_Tp>; -// -// template -// concept signed_integral = integral<_Tp> && is_signed_v<_Tp>; -// -// template -// concept unsigned_integral = integral<_Tp> && !signed_integral<_Tp>; -// -// template -// concept floating_point = is_floating_point_v<_Tp>; +template +concept integral = is_integral_v; + +template +concept signed_integral = is_signed_integer_v; + +template +concept unsigned_integral = integral && !signed_integral; + +template +concept floating_point = is_floating_point_v; /* -- 2.45.2 From b29695e1487331405c2d50c90faccba56c2e92f2 Mon Sep 17 00:00:00 2001 From: Andreas Tsouchlos Date: Thu, 17 Mar 2022 18:04:06 +0100 Subject: [PATCH 14/16] Replaced memcpy with manual while loop --- const_fmt/stdlib.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/const_fmt/stdlib.h b/const_fmt/stdlib.h index b963489..1636570 100644 --- a/const_fmt/stdlib.h +++ b/const_fmt/stdlib.h @@ -187,8 +187,10 @@ concept floating_point = is_floating_point_v; template -constexpr inline void copy(input_t* start, input_t* end, output_t* dest_start) { - memcpy(start, dest_start, end - start); +constexpr inline void copy(const input_t* start, const input_t* end, output_t* dest_start) { + auto temp = start; + while (temp != end) + *(dest_start++) = *(temp++); } -- 2.45.2 From ee1153c393bdd2d6e68be9e563f18cc52e4ccb5f Mon Sep 17 00:00:00 2001 From: Andreas Tsouchlos Date: Thu, 17 Mar 2022 22:11:30 +0100 Subject: [PATCH 15/16] Changed copy constructor signature of std::array implementation --- const_fmt/stdlib.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/const_fmt/stdlib.h b/const_fmt/stdlib.h index 1636570..026e01b 100644 --- a/const_fmt/stdlib.h +++ b/const_fmt/stdlib.h @@ -237,13 +237,10 @@ public: } constexpr array() noexcept = default; - - constexpr array(array&) = default; - + constexpr array(const array&) = default; constexpr array(array&&) = default; constexpr array& operator=(array& other) = default; - constexpr array& operator=(array&& other) = default; constexpr void swap(array& other) noexcept { -- 2.45.2 From 4d05a9a8fa512f5c61fe0baff4c19633c41d0be9 Mon Sep 17 00:00:00 2001 From: Andreas Tsouchlos Date: Thu, 17 Mar 2022 22:44:17 +0100 Subject: [PATCH 16/16] Added const versions of std::array::begin() and std::array::end() --- const_fmt/stdlib.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/const_fmt/stdlib.h b/const_fmt/stdlib.h index 026e01b..684f70a 100644 --- a/const_fmt/stdlib.h +++ b/const_fmt/stdlib.h @@ -240,7 +240,7 @@ public: constexpr array(const array&) = default; constexpr array(array&&) = default; - constexpr array& operator=(array& other) = default; + constexpr array& operator=(const array& other) = default; constexpr array& operator=(array&& other) = default; constexpr void swap(array& other) noexcept { @@ -271,6 +271,14 @@ public: return (&(m_data[t_size - 1]) + 1); } + constexpr const_iterator begin() const noexcept { + return &(m_data[0]); + } + + constexpr const_iterator end() const noexcept { + return (&(m_data[t_size - 1]) + 1); + } + constexpr const_iterator cbegin() const noexcept { return &(m_data[0]); } -- 2.45.2