Compare commits
8 Commits
v1.1
...
6ba83fd582
| Author | SHA1 | Date | |
|---|---|---|---|
| 6ba83fd582 | |||
| 8f7b1cd4e3 | |||
| ec70a5bba1 | |||
| 1263dfee98 | |||
| 52992e255e | |||
| 8526ae1d91 | |||
| b8f59710d3 | |||
| 184815c75b |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,4 +1,5 @@
|
|||||||
build
|
build
|
||||||
cmake-build-debug
|
cmake-build-debug
|
||||||
cmake-build-release
|
cmake-build-release
|
||||||
|
cmake-build-relwithdebinfo
|
||||||
.idea
|
.idea
|
||||||
|
|||||||
@@ -11,8 +11,7 @@ During compile-time, the string to be formatted is preprocessed to the point onl
|
|||||||
have to be written (If they are not available at compile time).
|
have to be written (If they are not available at compile time).
|
||||||
|
|
||||||
For example `One number: {:03}; And another one: {:05.3}` is preprocessed into `One number: 000; And another one: 00.000`.
|
For example `One number: {:03}; And another one: {:05.3}` is preprocessed into `One number: 000; And another one: 00.000`.
|
||||||
This is returned as a `std::array<char, N>`, where `N` is automatically evaluated. The only code executed at compile
|
This is returned as a `std::array<char, N>`, where `N` is automatically evaluated. The only code executed at runtime then formats the numbers and writes them into their places in the array.
|
||||||
time then formats the numbers and writes them into their place in the array.
|
|
||||||
|
|
||||||
Disclaimer: The actual formatting code is largely shamelessly stolen from `fmtlib`.
|
Disclaimer: The actual formatting code is largely shamelessly stolen from `fmtlib`.
|
||||||
|
|
||||||
@@ -48,8 +47,11 @@ $ ctest --test-dir build/
|
|||||||
|
|
||||||
## Limitations
|
## Limitations
|
||||||
|
|
||||||
|
For the compile time preprocessing of format strings non non-type template parameters are heavily relied upon,
|
||||||
|
which means C++20 is required.
|
||||||
|
|
||||||
Only a relatively limited subset of the `fmtlib` syntax is recognized (for now anyway). In particular,
|
Only a relatively limited subset of the `fmtlib` syntax is recognized (for now anyway). In particular,
|
||||||
there is no support for positional arguments, alignment, chrono format specs and custom const_format specifications.
|
float formatting in decimal and integer formatting in decimal, binary and hexadecimal are supported.
|
||||||
|
|
||||||
By nature of the library design, which forces compile-time preprocessing of the const_format string, no dynamic width or
|
By nature of the library design, which forces compile-time preprocessing of the const_format string, no dynamic width or
|
||||||
dynamic precision can be implemented.
|
dynamic precision can be implemented.
|
||||||
|
|||||||
127
const_fmt/std_lib.h
Normal file
127
const_fmt/std_lib.h
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
#ifndef CONST_FMT_STD_LIB_H
|
||||||
|
#define CONST_FMT_STD_LIB_H
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef CONST_FMT_NO_CPP_STD_LIB
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
|
||||||
|
|
||||||
|
using size_t = uint16_t;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* type_traits
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
|
||||||
|
template<typename T> struct remove_reference { using type = T; };
|
||||||
|
template<typename T> struct remove_reference<T&> { using type = T; };
|
||||||
|
template<typename T> struct remove_reference<T&&> { using type = T; };
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
using remove_reference_t = typename std::remove_reference<T>::type;
|
||||||
|
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* utility
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
std::remove_reference_t<T>&& move(T&& arg) noexcept {
|
||||||
|
return reinterpret_cast<std::remove_reference_t<T>&&>(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
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 <typename data_t, std::size_t t_size>
|
||||||
|
class array {
|
||||||
|
public:
|
||||||
|
template<typename... args_t>
|
||||||
|
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<data_t, t_size>& 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
data_t m_data[t_size];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace std
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif // CONST_FMT_STD_LIB_H
|
||||||
@@ -2,7 +2,8 @@
|
|||||||
#define LOGGER_TYPES_H
|
#define LOGGER_TYPES_H
|
||||||
|
|
||||||
|
|
||||||
#include <array>
|
|
||||||
|
#include "std_lib.h"
|
||||||
|
|
||||||
|
|
||||||
namespace const_fmt { namespace const_fmt_detail {
|
namespace const_fmt { namespace const_fmt_detail {
|
||||||
@@ -19,8 +20,8 @@ template <std::size_t N>
|
|||||||
class ConstString {
|
class ConstString {
|
||||||
public:
|
public:
|
||||||
constexpr ConstString(const char (&content)[N]) noexcept {
|
constexpr ConstString(const char (&content)[N]) noexcept {
|
||||||
std::copy(std::begin(content), std::end(content),
|
std::copy(&content[0], (&content[N-1] + 1),
|
||||||
std::begin(m_content));
|
m_content.begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr char operator[](std::size_t index) const noexcept {
|
constexpr char operator[](std::size_t index) const noexcept {
|
||||||
|
|||||||
@@ -2,8 +2,9 @@
|
|||||||
#define LOGGER_UTILITY_H
|
#define LOGGER_UTILITY_H
|
||||||
|
|
||||||
|
|
||||||
#include <cstring>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "std_lib.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user