Start work on formatting
This commit is contained in:
1
.bazelrc
1
.bazelrc
@ -14,3 +14,4 @@ build --cxxopt=-Wno-c++20-compat
|
||||
build --cxxopt=-Wno-unused-macros
|
||||
build --cxxopt=-Wno-documentation-unknown-command
|
||||
build --cxxopt=-Wno-extra-semi-stmt
|
||||
build --cxxopt=-Wno-extra-semi
|
||||
|
@ -28,4 +28,3 @@ Checks:
|
||||
- "-*-no-array-decay"
|
||||
- "-*-signed-bitwise"
|
||||
- "-readability-use-anyofallof"
|
||||
|
||||
|
@ -3,6 +3,7 @@ cc_library(
|
||||
hdrs = [
|
||||
"annotations.hpp",
|
||||
"assert.hpp",
|
||||
"format.hpp",
|
||||
"integers.hpp",
|
||||
"layout.hpp",
|
||||
"maybe_uninit.hpp",
|
||||
@ -11,6 +12,9 @@ cc_library(
|
||||
"option.hpp",
|
||||
"utility.hpp",
|
||||
],
|
||||
srcs = [
|
||||
"format.cpp",
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
@ -23,4 +27,11 @@ cc_library(
|
||||
deps = [
|
||||
":asl",
|
||||
],
|
||||
) for name in ["integers", "maybe_uninit", "meta", "option", "utility"]]
|
||||
) for name in [
|
||||
"format",
|
||||
"integers",
|
||||
"maybe_uninit",
|
||||
"meta",
|
||||
"option",
|
||||
"utility",
|
||||
]]
|
||||
|
12
asl/format.cpp
Normal file
12
asl/format.cpp
Normal file
@ -0,0 +1,12 @@
|
||||
#include "asl/format.hpp"
|
||||
|
||||
void asl::format_internals::format(
|
||||
writer* writer,
|
||||
const char* fmt,
|
||||
const type_erased_arg* args,
|
||||
int64_t arg_count)
|
||||
{
|
||||
formatter f(writer);
|
||||
|
||||
f.write("Hello", 5);
|
||||
}
|
84
asl/format.hpp
Normal file
84
asl/format.hpp
Normal file
@ -0,0 +1,84 @@
|
||||
#pragma once
|
||||
|
||||
#include "asl/integers.hpp"
|
||||
#include "asl/meta.hpp"
|
||||
#include "asl/utility.hpp"
|
||||
|
||||
namespace asl
|
||||
{
|
||||
|
||||
// @Todo Move this to io
|
||||
class writer
|
||||
{
|
||||
public:
|
||||
writer() = default;
|
||||
ASL_DELETE_COPY_MOVE(writer);
|
||||
virtual ~writer() = default;
|
||||
|
||||
// @Todo Use string view, or span of bytes?
|
||||
virtual void write(const char* str, int64_t len) = 0;
|
||||
};
|
||||
|
||||
class formatter;
|
||||
|
||||
template<typename T>
|
||||
concept formattable = requires (formatter& f, const T& value)
|
||||
{
|
||||
AslFormat(f, value);
|
||||
};
|
||||
|
||||
namespace format_internals
|
||||
{
|
||||
|
||||
struct type_erased_arg
|
||||
{
|
||||
const void* data;
|
||||
void (*fn)(formatter&, const void*);
|
||||
|
||||
template<formattable T>
|
||||
static constexpr void erased_fn(formatter& f, const void* data)
|
||||
{
|
||||
AslFormat(f, *reinterpret_cast<const T*>(data));
|
||||
}
|
||||
|
||||
template<formattable T>
|
||||
explicit constexpr type_erased_arg(const T& arg)
|
||||
: data{&arg}
|
||||
, fn{erased_fn<T>}
|
||||
{}
|
||||
};
|
||||
|
||||
// @Todo Use span
|
||||
void format(writer*, const char* fmt, const type_erased_arg* args, int64_t arg_count);
|
||||
|
||||
} // internals
|
||||
|
||||
class formatter
|
||||
{
|
||||
writer* m_writer;
|
||||
|
||||
public:
|
||||
explicit constexpr formatter(writer* writer)
|
||||
: m_writer{writer}
|
||||
{}
|
||||
|
||||
// @Todo Use string_view
|
||||
constexpr void write(const char* s, int64_t len)
|
||||
{
|
||||
m_writer->write(s, len);
|
||||
}
|
||||
};
|
||||
|
||||
// @Todo Use string_view
|
||||
template<typename... Args>
|
||||
void format(writer* w, const char* fmt, const Args&... args)
|
||||
{
|
||||
auto type_erased_args[] = {
|
||||
format_internals::type_erased_arg(args)...
|
||||
};
|
||||
|
||||
// @Todo Use array extent
|
||||
format_internals::format(w, fmt, type_erased_args, types_count<Args...>);
|
||||
}
|
||||
|
||||
} // namespace asl
|
0
asl/format_tests.cpp
Normal file
0
asl/format_tests.cpp
Normal file
@ -1,11 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include "asl/integers.hpp"
|
||||
|
||||
namespace asl {
|
||||
|
||||
struct empty {};
|
||||
|
||||
template<typename T> struct id { using type = T; };
|
||||
|
||||
template<typename... Args> static constexpr int64_t types_count = sizeof...(Args);
|
||||
|
||||
template<typename T, T kValue> struct integral_constant { static constexpr T value = kValue; };
|
||||
template<bool B> using bool_constant = integral_constant<bool, B>;
|
||||
|
||||
|
@ -158,4 +158,9 @@ static_assert(asl::is_same<int, asl::un_ref_t<int&>>);
|
||||
static_assert(asl::is_same<int, asl::un_ref_t<int&&>>);
|
||||
static_assert(asl::is_same<int() &, asl::un_ref_t<int() &>>);
|
||||
|
||||
static_assert(asl::types_count<int, float> == 2);
|
||||
static_assert(asl::types_count<int, int> == 2);
|
||||
static_assert(asl::types_count<int> == 1);
|
||||
static_assert(asl::types_count<> == 0);
|
||||
|
||||
int main() { return 0; }
|
||||
|
@ -116,7 +116,6 @@ public:
|
||||
m_has_value = false;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} // namespace asl
|
||||
|
@ -17,4 +17,16 @@ T exchange(T& obj, U&& new_value)
|
||||
return old_value;
|
||||
}
|
||||
|
||||
#define ASL_DELETE_COPY(T) \
|
||||
T(const T&) = delete; \
|
||||
T& operator=(const T&) = delete;
|
||||
|
||||
#define ASL_DELETE_MOVE(T) \
|
||||
T(T&&) = delete; \
|
||||
T& operator=(T&&) = delete;
|
||||
|
||||
#define ASL_DELETE_COPY_MOVE(T) \
|
||||
ASL_DELETE_COPY(T) \
|
||||
ASL_DELETE_MOVE(T)
|
||||
|
||||
} // namespace asl
|
||||
|
Reference in New Issue
Block a user