Skip to content

Commit 13afb2c

Browse files
author
Hana Dusíková
committed
formating
1 parent c6f48af commit 13afb2c

File tree

8 files changed

+267
-1
lines changed

8 files changed

+267
-1
lines changed

Makefile

+5-1
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,15 @@ benchmark-clean:
4242
clean:
4343
rm -f $(TRUE_TARGETS) $(OBJECTS) $(DEPEDENCY_FILES) mtent12.txt mtent12.zip
4444

45-
grammar: include/ctre/pcre.hpp
45+
grammar: include/ctre/pcre.hpp include/ctfmt/fmt.hpp
4646

4747
regrammar:
4848
@rm -f include/ctre/pcre.hpp
4949
@$(MAKE) grammar
50+
51+
include/ctfmt/fmt.hpp: include/ctfmt/fmt.gram
52+
@echo "LL1q $<"
53+
@$(DESATOMAT) --ll --q --input=include/ctfmt/fmt.gram --output=include/ctfmt/ --generator=cpp_ctll_v2 --cfg:fname=fmt.hpp --cfg:namespace=ctfmt --cfg:guard=CTFMT__FMT__HPP --cfg:grammar_name=fmt
5054

5155
include/ctre/pcre.hpp: include/ctre/pcre.gram
5256
@echo "LL1q $<"

include/ctfmt.hpp

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#ifndef CTRE_V2__CTFMT__HPP
2+
#define CTRE_V2__CTFMT__HPP
3+
4+
#include "ctfmt/format.hpp"
5+
6+
#endif

include/ctfmt/actions.hpp

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#ifndef CTFMT__ACTIONS__HPP
2+
#define CTFMT__ACTIONS__HPP
3+
4+
#include <cstdint>
5+
#include <algorithm>
6+
#include <tuple>
7+
8+
namespace ctfmt {
9+
10+
template <int64_t Number> struct number { };
11+
template <int64_t Value> struct placeholder { };
12+
template <char... Text> struct text { };
13+
14+
template <int64_t Value, typename... Args> constexpr size_t calculate_size(placeholder<Value>, const std::tuple<Args...> & tuple) {
15+
return std::get<Value>(tuple).size();
16+
}
17+
18+
template <char... Text, typename... Args> constexpr size_t calculate_size(text<Text...>, const std::tuple<Args...> &) {
19+
return sizeof...(Text);
20+
}
21+
22+
template <int64_t Value, typename It, typename... Args> constexpr void format_into(placeholder<Value>, It & begin, const It, const std::tuple<Args...> & tuple) {
23+
const auto & obj = std::get<Value>(tuple);
24+
begin = std::copy(obj.begin(), obj.end(), begin);
25+
}
26+
27+
template <char... Text, typename It, typename... Args> constexpr void format_into(text<Text...>, It & begin, const It, const std::tuple<Args...> &) {
28+
((*begin++ = Text), ...);
29+
}
30+
31+
template <typename...> struct sequence { };
32+
33+
struct actions {
34+
35+
36+
template <auto V, typename... Ts> static constexpr auto apply(fmt::start_text, ctll::term<V>, ctll::list<Ts...>) {
37+
return ctll::list<text<V>, Ts...>{};
38+
}
39+
40+
template <char... Text, auto V, typename... Ts> static constexpr auto apply(fmt::push_text, ctll::term<V>, ctll::list<text<Text...>, Ts...>) {
41+
return ctll::list<text<Text..., V>, Ts...>{};
42+
}
43+
44+
template <char... Text, typename Symbol, typename... Ts> static constexpr auto apply(fmt::finish, Symbol, ctll::list<text<Text...>, sequence<Ts...>>) {
45+
return ctll::list<sequence<Ts..., text<Text...>>>{};
46+
}
47+
48+
template <auto V, typename... Ts> static constexpr auto apply(fmt::start_digit, ctll::term<V>, ctll::list<Ts...>) {
49+
return ctll::list<number<(V - '0')>, Ts...>{};
50+
}
51+
52+
template <int64_t Value, auto V, typename... Ts> static constexpr auto apply(fmt::push_digit, ctll::term<V>, ctll::list<number<Value>, Ts...>) {
53+
return ctll::list<number<(Value * 10 + (V - '0'))>, Ts...>{};
54+
}
55+
56+
template <int64_t Value, typename Symbol, typename... Ts> static constexpr auto apply(fmt::finish, Symbol, ctll::list<number<Value>, sequence<Ts...>>) {
57+
return ctll::list<sequence<Ts..., placeholder<Value>>>{};
58+
}
59+
60+
61+
62+
};
63+
64+
}
65+
66+
#endif

include/ctfmt/fmt.gram

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
digit={0,1,2,3,4,5,6,7,8,9}
2+
3+
S-><text>,<S2>|<placeholder>,<S>|epsilon
4+
S2-><placeholder>,<S>|epsilon
5+
6+
text->other,[start_text],<text2>
7+
text2->other,[push_text],<text2>|epsilon,[finish]
8+
placeholder->{,<number>,[finish],}
9+
number->digit,[start_digit],<number2>
10+
number2->digit,[push_digit],<number2>|epsilon

include/ctfmt/fmt.hpp

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#ifndef CTFMT__FMT__HPP
2+
#define CTFMT__FMT__HPP
3+
4+
// THIS FILE WAS GENERATED BY DESATOMAT TOOL, DO NOT MODIFY THIS FILE
5+
6+
#include "../ctll/grammars.hpp"
7+
8+
namespace ctfmt {
9+
10+
struct fmt {
11+
12+
// NONTERMINALS:
13+
struct number2 {};
14+
struct number {};
15+
struct s2 {};
16+
struct s {}; using _start = s;
17+
struct text2 {};
18+
19+
// 'action' types:
20+
struct finish: ctll::action {};
21+
struct push_digit: ctll::action {};
22+
struct push_text: ctll::action {};
23+
struct start_digit: ctll::action {};
24+
struct start_text: ctll::action {};
25+
26+
// (q)LL1 function:
27+
using _others = ctll::neg_set<'\x7B','\x7D','0','1','2','3','4','5','6','7','8','9'>;
28+
static constexpr auto rule(s, ctll::epsilon) -> ctll::epsilon;
29+
static constexpr auto rule(s, ctll::term<'\x7B'>) -> ctll::push<ctll::anything, number, finish, ctll::term<'\x7D'>, s>;
30+
static constexpr auto rule(s, _others) -> ctll::push<ctll::anything, start_text, text2, s2>;
31+
static constexpr auto rule(s, ctll::set<'\x7D','0','1','2','3','4','5','6','7','8','9'>) -> ctll::reject;
32+
33+
static constexpr auto rule(number2, ctll::term<'\x7D'>) -> ctll::epsilon;
34+
static constexpr auto rule(number2, ctll::set<'0','1','2','3','4','5','6','7','8','9'>) -> ctll::push<ctll::anything, push_digit, number2>;
35+
36+
static constexpr auto rule(number, ctll::set<'0','1','2','3','4','5','6','7','8','9'>) -> ctll::push<ctll::anything, start_digit, number2>;
37+
38+
static constexpr auto rule(s2, ctll::epsilon) -> ctll::epsilon;
39+
static constexpr auto rule(s2, ctll::term<'\x7B'>) -> ctll::push<ctll::anything, number, finish, ctll::term<'\x7D'>, s>;
40+
41+
static constexpr auto rule(text2, _others) -> ctll::push<ctll::anything, push_text, text2>;
42+
static constexpr auto rule(text2, ctll::term<'\x7B'>) -> ctll::push<finish>;
43+
static constexpr auto rule(text2, ctll::epsilon) -> ctll::push<finish>;
44+
static constexpr auto rule(text2, ctll::set<'\x7D','0','1','2','3','4','5','6','7','8','9'>) -> ctll::reject;
45+
46+
};
47+
48+
}
49+
50+
#endif //CTFMT__FMT__HPP

include/ctfmt/format.hpp

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
#ifndef CTFMT__TO_STRING__HPP
2+
#define CTFMT__TO_STRING__HPP
3+
4+
#include "utility.hpp"
5+
#include "../ctll/parser.hpp"
6+
#include "fmt.hpp"
7+
#include "actions.hpp"
8+
#include <string_view>
9+
#include <string>
10+
#include <tuple>
11+
#include "utility.hpp"
12+
#include <cassert>
13+
#include <array>
14+
15+
namespace ctfmt {
16+
17+
struct buffer_wrap {
18+
19+
};
20+
21+
struct view_wrap {
22+
std::string_view view;
23+
constexpr view_wrap(std::string_view view) noexcept: view{view} { }
24+
constexpr size_t size() const noexcept {
25+
return view.size();
26+
}
27+
constexpr auto begin() const noexcept {
28+
return view.begin();
29+
}
30+
constexpr auto end() const noexcept {
31+
return view.end();
32+
}
33+
};
34+
35+
CTLL_FORCE_INLINE constexpr view_wrap input_wrap(const char * str) {
36+
return view_wrap{std::string_view(str)};
37+
}
38+
39+
CTLL_FORCE_INLINE constexpr view_wrap input_wrap(std::string_view v) {
40+
return view_wrap{v};
41+
}
42+
43+
CTLL_FORCE_INLINE inline view_wrap input_wrap(const std::string & s) {
44+
return view_wrap{std::string_view(s)};
45+
}
46+
47+
template <typename... Seq, typename... Args> CTFMT_FORCE_INLINE auto calculate_size_with_impl(sequence<Seq...>, const std::tuple<Args...> & args) {
48+
return (calculate_size(Seq(), args) + ... + 0);
49+
}
50+
51+
template <typename Seq, typename... Args> CTFMT_FORCE_INLINE auto calculate_size_with(const std::tuple<Args...> & args) {
52+
return calculate_size_with_impl(Seq(), args);
53+
}
54+
55+
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) {
56+
(format_into(Seq(), begin, end, args), ...);
57+
}
58+
59+
template <typename Seq, typename It, typename... Args> CTFMT_FORCE_INLINE void format_with(It begin, It end, const std::tuple<Args ...> & args) {
60+
format_with_impl(Seq(), begin, end, args);
61+
}
62+
63+
template <typename Seq> struct format_object {
64+
template <typename... Args> CTFMT_FORCE_INLINE auto format(std::tuple<Args...> args) {
65+
std::string output;
66+
output.resize(calculate_size_with<Seq>(args));
67+
format_with<Seq>(output.begin(), output.end(), args);
68+
return output;
69+
}
70+
template <size_t Size, typename... Args> CTFMT_FORCE_INLINE auto format(std::array<char, Size> & buffer, std::tuple<Args...> args) {
71+
size_t size = calculate_size_with<Seq>(args);
72+
assert(Size >= size);
73+
format_with<Seq>(buffer.begin(), buffer.end(), args);
74+
return std::string_view(buffer.begin(), size);
75+
}
76+
template <typename... Args> CTFMT_FORCE_INLINE auto operator()(Args && ... args) {
77+
return format(std::make_tuple(input_wrap(std::forward<Args>(args))...));
78+
}
79+
template <size_t Size, typename... Args> CTFMT_FORCE_INLINE auto operator()(std::array<char, Size> & buffer, Args && ... args) {
80+
return format(buffer, std::make_tuple(input_wrap(std::forward<Args>(args))...));
81+
}
82+
};
83+
84+
#if __cpp_nontype_template_parameter_class
85+
template <ctll::basic_fixed_string input> CTFMT_FLATTEN constexpr auto format() noexcept {
86+
constexpr auto _input = input;
87+
#else
88+
template <auto & input> CTFMT_FLATTEN constexpr auto format() noexcept {
89+
constexpr auto & _input = input;
90+
#endif
91+
92+
//using tmp = typename ctll::parser<ctfmt::fmt, _input, ctfmt::actions>::template output<ctll::list<>>;
93+
using tmp = typename ctll::parser<ctfmt::fmt, _input, ctfmt::actions>::template output<ctll::list<sequence<>>>;
94+
static_assert(tmp(), "Format Expression contains syntax error.");
95+
return format_object<decltype(ctll::front(typename tmp::output_type()))>();
96+
}
97+
98+
}
99+
100+
#endif

include/ctfmt/utility.hpp

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#ifndef CTFMT__UTILITY__HPP
2+
#define CTFMT__UTILITY__HPP
3+
4+
#ifdef _MSC_VER
5+
#define CTFMT_FORCE_INLINE __forceinline
6+
#define CTFMT_FLATTEN
7+
#else
8+
#define CTFMT_FORCE_INLINE inline __attribute__((always_inline))
9+
#define CTFMT_FLATTEN __attribute__((flatten))
10+
#endif
11+
12+
#endif

tests/fmt.cpp

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#include <ctfmt.hpp>
2+
#include <iostream>
3+
4+
5+
static constexpr ctll::basic_fixed_string pattern = "Hello {1} from {0}!\n";
6+
7+
template <typename T> struct identify;
8+
9+
int main() {
10+
auto fmt = ctfmt::format<pattern>();
11+
//identify<decltype(fmt)> hello;
12+
std::array<char, 64> buffer;
13+
14+
std::string_view a = fmt(buffer, "Hana","std::format");
15+
fwrite(a.data(), a.size(), 1, stdout);
16+
std::string_view b = fmt(buffer, "C++20","programmers");
17+
fwrite(b.data(), b.size(), 1, stdout);
18+
}

0 commit comments

Comments
 (0)