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 73748f9..afad960 100644 --- a/const_fmt/format_impl.h +++ b/const_fmt/format_impl.h @@ -12,6 +12,7 @@ #include +#include "stdlib.h" #include "utility.h" @@ -119,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/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 { diff --git a/const_fmt/stdlib.h b/const_fmt/stdlib.h new file mode 100644 index 0000000..684f70a --- /dev/null +++ b/const_fmt/stdlib.h @@ -0,0 +1,300 @@ +#ifndef CONST_FMT_STDLIB_H +#define CONST_FMT_STDLIB_H + + +/* + * + * 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) + * + */ + + +#ifndef CONST_FMT_NO_CPP_STDLIB + +#include +#include + +#else + +#include +#include + + +namespace const_fmt { namespace std { + + +using size_t = uint16_t; + + +/* + * + * type_traits + * + */ + + +// various + + +constexpr inline bool is_constant_evaluated() noexcept { + return __builtin_is_constant_evaluated(); +} + +struct true_type { + constexpr static bool value = true; +}; + +struct false_type { + constexpr static bool value = false; +}; + + +// is_same + + +template +struct is_same : public false_type {}; + +template +struct is_same : public true_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; }; +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_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; + +// clang-format on + + +// is_integral + + +template +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 +using is_floating_point = + is_one_of, float, double, long double>; + + +// make_unsigned + + +// 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 + + +// 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 + * + */ + + +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; + + +/* + * + * algorithm + * + */ + + +template +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++); +} + + +/* + * + * utility + * + */ + + +template +std::remove_reference_t&& move(T&& arg) noexcept { + return reinterpret_cast&&>(arg); +} + +template +constexpr inline 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(const array&) = default; + constexpr array(array&&) = default; + + constexpr array& operator=(const 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 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]); + } + + 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 071937a..a8caf66 100644 --- a/const_fmt/types.h +++ b/const_fmt/types.h @@ -2,7 +2,8 @@ #define LOGGER_TYPES_H -#include + +#include "stdlib.h" namespace const_fmt { namespace const_fmt_detail { @@ -19,8 +20,7 @@ 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..2e41a3d 100644 --- a/const_fmt/utility.h +++ b/const_fmt/utility.h @@ -2,8 +2,9 @@ #define LOGGER_UTILITY_H -#include +#include +#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