Skip to content

Commit

Permalink
formating
Browse files Browse the repository at this point in the history
  • Loading branch information
Hana Dusíková committed Feb 19, 2019
1 parent c6f48af commit 13afb2c
Show file tree
Hide file tree
Showing 8 changed files with 267 additions and 1 deletion.
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,15 @@ benchmark-clean:
clean:
rm -f $(TRUE_TARGETS) $(OBJECTS) $(DEPEDENCY_FILES) mtent12.txt mtent12.zip

grammar: include/ctre/pcre.hpp
grammar: include/ctre/pcre.hpp include/ctfmt/fmt.hpp

regrammar:
@rm -f include/ctre/pcre.hpp
@$(MAKE) grammar

include/ctfmt/fmt.hpp: include/ctfmt/fmt.gram
@echo "LL1q $<"
@$(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

include/ctre/pcre.hpp: include/ctre/pcre.gram
@echo "LL1q $<"
Expand Down
6 changes: 6 additions & 0 deletions include/ctfmt.hpp
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
66 changes: 66 additions & 0 deletions include/ctfmt/actions.hpp
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
10 changes: 10 additions & 0 deletions include/ctfmt/fmt.gram
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
50 changes: 50 additions & 0 deletions include/ctfmt/fmt.hpp
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
100 changes: 100 additions & 0 deletions include/ctfmt/format.hpp
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
12 changes: 12 additions & 0 deletions include/ctfmt/utility.hpp
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
18 changes: 18 additions & 0 deletions tests/fmt.cpp
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);
}

0 comments on commit 13afb2c

Please sign in to comment.