-
Notifications
You must be signed in to change notification settings - Fork 190
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Hana Dusíková
committed
Feb 19, 2019
1 parent
c6f48af
commit 13afb2c
Showing
8 changed files
with
267 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#ifndef CTRE_V2__CTFMT__HPP | ||
#define CTRE_V2__CTFMT__HPP | ||
|
||
#include "ctfmt/format.hpp" | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
#ifndef CTFMT__ACTIONS__HPP | ||
#define CTFMT__ACTIONS__HPP | ||
|
||
#include <cstdint> | ||
#include <algorithm> | ||
#include <tuple> | ||
|
||
namespace ctfmt { | ||
|
||
template <int64_t Number> struct number { }; | ||
template <int64_t Value> struct placeholder { }; | ||
template <char... Text> struct text { }; | ||
|
||
template <int64_t Value, typename... Args> constexpr size_t calculate_size(placeholder<Value>, const std::tuple<Args...> & tuple) { | ||
return std::get<Value>(tuple).size(); | ||
} | ||
|
||
template <char... Text, typename... Args> constexpr size_t calculate_size(text<Text...>, const std::tuple<Args...> &) { | ||
return sizeof...(Text); | ||
} | ||
|
||
template <int64_t Value, typename It, typename... Args> constexpr void format_into(placeholder<Value>, It & begin, const It, const std::tuple<Args...> & tuple) { | ||
const auto & obj = std::get<Value>(tuple); | ||
begin = std::copy(obj.begin(), obj.end(), begin); | ||
} | ||
|
||
template <char... Text, typename It, typename... Args> constexpr void format_into(text<Text...>, It & begin, const It, const std::tuple<Args...> &) { | ||
((*begin++ = Text), ...); | ||
} | ||
|
||
template <typename...> struct sequence { }; | ||
|
||
struct actions { | ||
|
||
|
||
template <auto V, typename... Ts> static constexpr auto apply(fmt::start_text, ctll::term<V>, ctll::list<Ts...>) { | ||
return ctll::list<text<V>, Ts...>{}; | ||
} | ||
|
||
template <char... Text, auto V, typename... Ts> static constexpr auto apply(fmt::push_text, ctll::term<V>, ctll::list<text<Text...>, Ts...>) { | ||
return ctll::list<text<Text..., V>, Ts...>{}; | ||
} | ||
|
||
template <char... Text, typename Symbol, typename... Ts> static constexpr auto apply(fmt::finish, Symbol, ctll::list<text<Text...>, sequence<Ts...>>) { | ||
return ctll::list<sequence<Ts..., text<Text...>>>{}; | ||
} | ||
|
||
template <auto V, typename... Ts> static constexpr auto apply(fmt::start_digit, ctll::term<V>, ctll::list<Ts...>) { | ||
return ctll::list<number<(V - '0')>, Ts...>{}; | ||
} | ||
|
||
template <int64_t Value, auto V, typename... Ts> static constexpr auto apply(fmt::push_digit, ctll::term<V>, ctll::list<number<Value>, Ts...>) { | ||
return ctll::list<number<(Value * 10 + (V - '0'))>, Ts...>{}; | ||
} | ||
|
||
template <int64_t Value, typename Symbol, typename... Ts> static constexpr auto apply(fmt::finish, Symbol, ctll::list<number<Value>, sequence<Ts...>>) { | ||
return ctll::list<sequence<Ts..., placeholder<Value>>>{}; | ||
} | ||
|
||
|
||
|
||
}; | ||
|
||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
digit={0,1,2,3,4,5,6,7,8,9} | ||
|
||
S-><text>,<S2>|<placeholder>,<S>|epsilon | ||
S2-><placeholder>,<S>|epsilon | ||
|
||
text->other,[start_text],<text2> | ||
text2->other,[push_text],<text2>|epsilon,[finish] | ||
placeholder->{,<number>,[finish],} | ||
number->digit,[start_digit],<number2> | ||
number2->digit,[push_digit],<number2>|epsilon |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
#ifndef CTFMT__FMT__HPP | ||
#define CTFMT__FMT__HPP | ||
|
||
// THIS FILE WAS GENERATED BY DESATOMAT TOOL, DO NOT MODIFY THIS FILE | ||
|
||
#include "../ctll/grammars.hpp" | ||
|
||
namespace ctfmt { | ||
|
||
struct fmt { | ||
|
||
// NONTERMINALS: | ||
struct number2 {}; | ||
struct number {}; | ||
struct s2 {}; | ||
struct s {}; using _start = s; | ||
struct text2 {}; | ||
|
||
// 'action' types: | ||
struct finish: ctll::action {}; | ||
struct push_digit: ctll::action {}; | ||
struct push_text: ctll::action {}; | ||
struct start_digit: ctll::action {}; | ||
struct start_text: ctll::action {}; | ||
|
||
// (q)LL1 function: | ||
using _others = ctll::neg_set<'\x7B','\x7D','0','1','2','3','4','5','6','7','8','9'>; | ||
static constexpr auto rule(s, ctll::epsilon) -> ctll::epsilon; | ||
static constexpr auto rule(s, ctll::term<'\x7B'>) -> ctll::push<ctll::anything, number, finish, ctll::term<'\x7D'>, s>; | ||
static constexpr auto rule(s, _others) -> ctll::push<ctll::anything, start_text, text2, s2>; | ||
static constexpr auto rule(s, ctll::set<'\x7D','0','1','2','3','4','5','6','7','8','9'>) -> ctll::reject; | ||
|
||
static constexpr auto rule(number2, ctll::term<'\x7D'>) -> ctll::epsilon; | ||
static constexpr auto rule(number2, ctll::set<'0','1','2','3','4','5','6','7','8','9'>) -> ctll::push<ctll::anything, push_digit, number2>; | ||
|
||
static constexpr auto rule(number, ctll::set<'0','1','2','3','4','5','6','7','8','9'>) -> ctll::push<ctll::anything, start_digit, number2>; | ||
|
||
static constexpr auto rule(s2, ctll::epsilon) -> ctll::epsilon; | ||
static constexpr auto rule(s2, ctll::term<'\x7B'>) -> ctll::push<ctll::anything, number, finish, ctll::term<'\x7D'>, s>; | ||
|
||
static constexpr auto rule(text2, _others) -> ctll::push<ctll::anything, push_text, text2>; | ||
static constexpr auto rule(text2, ctll::term<'\x7B'>) -> ctll::push<finish>; | ||
static constexpr auto rule(text2, ctll::epsilon) -> ctll::push<finish>; | ||
static constexpr auto rule(text2, ctll::set<'\x7D','0','1','2','3','4','5','6','7','8','9'>) -> ctll::reject; | ||
|
||
}; | ||
|
||
} | ||
|
||
#endif //CTFMT__FMT__HPP |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
#ifndef CTFMT__TO_STRING__HPP | ||
#define CTFMT__TO_STRING__HPP | ||
|
||
#include "utility.hpp" | ||
#include "../ctll/parser.hpp" | ||
#include "fmt.hpp" | ||
#include "actions.hpp" | ||
#include <string_view> | ||
#include <string> | ||
#include <tuple> | ||
#include "utility.hpp" | ||
#include <cassert> | ||
#include <array> | ||
|
||
namespace ctfmt { | ||
|
||
struct buffer_wrap { | ||
|
||
}; | ||
|
||
struct view_wrap { | ||
std::string_view view; | ||
constexpr view_wrap(std::string_view view) noexcept: view{view} { } | ||
constexpr size_t size() const noexcept { | ||
return view.size(); | ||
} | ||
constexpr auto begin() const noexcept { | ||
return view.begin(); | ||
} | ||
constexpr auto end() const noexcept { | ||
return view.end(); | ||
} | ||
}; | ||
|
||
CTLL_FORCE_INLINE constexpr view_wrap input_wrap(const char * str) { | ||
return view_wrap{std::string_view(str)}; | ||
} | ||
|
||
CTLL_FORCE_INLINE constexpr view_wrap input_wrap(std::string_view v) { | ||
return view_wrap{v}; | ||
} | ||
|
||
CTLL_FORCE_INLINE inline view_wrap input_wrap(const std::string & s) { | ||
return view_wrap{std::string_view(s)}; | ||
} | ||
|
||
template <typename... Seq, typename... Args> CTFMT_FORCE_INLINE auto calculate_size_with_impl(sequence<Seq...>, const std::tuple<Args...> & args) { | ||
return (calculate_size(Seq(), args) + ... + 0); | ||
} | ||
|
||
template <typename Seq, typename... Args> CTFMT_FORCE_INLINE auto calculate_size_with(const std::tuple<Args...> & args) { | ||
return calculate_size_with_impl(Seq(), args); | ||
} | ||
|
||
template <typename... Seq, typename It, typename... Args> CTFMT_FORCE_INLINE void format_with_impl(sequence<Seq...>, It begin, It end, const std::tuple<Args ...> & args) { | ||
(format_into(Seq(), begin, end, args), ...); | ||
} | ||
|
||
template <typename Seq, typename It, typename... Args> CTFMT_FORCE_INLINE void format_with(It begin, It end, const std::tuple<Args ...> & args) { | ||
format_with_impl(Seq(), begin, end, args); | ||
} | ||
|
||
template <typename Seq> struct format_object { | ||
template <typename... Args> CTFMT_FORCE_INLINE auto format(std::tuple<Args...> args) { | ||
std::string output; | ||
output.resize(calculate_size_with<Seq>(args)); | ||
format_with<Seq>(output.begin(), output.end(), args); | ||
return output; | ||
} | ||
template <size_t Size, typename... Args> CTFMT_FORCE_INLINE auto format(std::array<char, Size> & buffer, std::tuple<Args...> args) { | ||
size_t size = calculate_size_with<Seq>(args); | ||
assert(Size >= size); | ||
format_with<Seq>(buffer.begin(), buffer.end(), args); | ||
return std::string_view(buffer.begin(), size); | ||
} | ||
template <typename... Args> CTFMT_FORCE_INLINE auto operator()(Args && ... args) { | ||
return format(std::make_tuple(input_wrap(std::forward<Args>(args))...)); | ||
} | ||
template <size_t Size, typename... Args> CTFMT_FORCE_INLINE auto operator()(std::array<char, Size> & buffer, Args && ... args) { | ||
return format(buffer, std::make_tuple(input_wrap(std::forward<Args>(args))...)); | ||
} | ||
}; | ||
|
||
#if __cpp_nontype_template_parameter_class | ||
template <ctll::basic_fixed_string input> CTFMT_FLATTEN constexpr auto format() noexcept { | ||
constexpr auto _input = input; | ||
#else | ||
template <auto & input> CTFMT_FLATTEN constexpr auto format() noexcept { | ||
constexpr auto & _input = input; | ||
#endif | ||
|
||
//using tmp = typename ctll::parser<ctfmt::fmt, _input, ctfmt::actions>::template output<ctll::list<>>; | ||
using tmp = typename ctll::parser<ctfmt::fmt, _input, ctfmt::actions>::template output<ctll::list<sequence<>>>; | ||
static_assert(tmp(), "Format Expression contains syntax error."); | ||
return format_object<decltype(ctll::front(typename tmp::output_type()))>(); | ||
} | ||
|
||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
#ifndef CTFMT__UTILITY__HPP | ||
#define CTFMT__UTILITY__HPP | ||
|
||
#ifdef _MSC_VER | ||
#define CTFMT_FORCE_INLINE __forceinline | ||
#define CTFMT_FLATTEN | ||
#else | ||
#define CTFMT_FORCE_INLINE inline __attribute__((always_inline)) | ||
#define CTFMT_FLATTEN __attribute__((flatten)) | ||
#endif | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#include <ctfmt.hpp> | ||
#include <iostream> | ||
|
||
|
||
static constexpr ctll::basic_fixed_string pattern = "Hello {1} from {0}!\n"; | ||
|
||
template <typename T> struct identify; | ||
|
||
int main() { | ||
auto fmt = ctfmt::format<pattern>(); | ||
//identify<decltype(fmt)> hello; | ||
std::array<char, 64> buffer; | ||
|
||
std::string_view a = fmt(buffer, "Hana","std::format"); | ||
fwrite(a.data(), a.size(), 1, stdout); | ||
std::string_view b = fmt(buffer, "C++20","programmers"); | ||
fwrite(b.data(), b.size(), 1, stdout); | ||
} |