├── main.cpp ├── .gitignore ├── README.md ├── LICENSE └── include ├── tools.hpp ├── string.hpp └── format.hpp /main.cpp: -------------------------------------------------------------------------------- 1 | #include "include/format.hpp" 2 | #include 3 | 4 | int main() 5 | { 6 | constexpr auto tmp = " {2} d {} {} {1} end"_format(2_s, "hello"_s, 3.14_s); 7 | std::cout << '\'' << tmp.c_str << '\'' << std::endl; 8 | } 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Compiled Dynamic libraries 12 | *.so 13 | *.dylib 14 | *.dll 15 | 16 | # Fortran module files 17 | *.mod 18 | *.smod 19 | 20 | # Compiled Static libraries 21 | *.lai 22 | *.la 23 | *.a 24 | *.lib 25 | 26 | # Executables 27 | *.exe 28 | *.out 29 | *.app 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # compile-time-string-format 2 | a c++17 header library that implements a user-defined literals operator for a compile time string format. 3 | ### Example 4 | 5 | ```c++ 6 | #include "include/format.hpp" 7 | #include 8 | 9 | int main() 10 | { 11 | constexpr auto str = "/home/{}/folder/{}"_format("name"_s, "file1"_s); 12 | constexpr auto str2 = "{0}+{0} = {1}"_format("1"_s, 2_s); 13 | 14 | std::cout << str.c_str << std::endl; // /home/name/folder/file1 15 | std::cout << str2.c_str << std::endl; // 1+1 = 2 16 | } 17 | ``` 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Bastien Penavayre 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /include/tools.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Bastien Penavayre 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include "string.hpp" 26 | 27 | namespace constexpr_string 28 | { 29 | template 30 | constexpr int atoi() 31 | { 32 | if constexpr (I >= String::size) return value * sign; 33 | else if constexpr (!started) 34 | { 35 | if constexpr (!"-0123456789"_s.contains(String::instance[I])) return atoi(); 36 | else if (String::instance[I] == '-') return atoi(); 37 | else return atoi(); 38 | } 39 | else if constexpr (!"0123456789"_s.contains(String::instance[I])) return value * sign; 40 | else return atoi(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /include/string.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Bastien Penavayre 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | #pragma once 23 | 24 | #include //size_t forward_as_tuple 25 | #include //std::index_sequence 26 | 27 | namespace constexpr_string 28 | { 29 | template 30 | struct string 31 | { 32 | static constexpr char c_str[sizeof...(Chars)+1] = {Chars..., '\0'}; 33 | static constexpr string instance = {}; 34 | static constexpr size_t size = sizeof...(Chars); 35 | 36 | constexpr bool operator==(string const &) const { return true; } 37 | 38 | template constexpr 39 | bool operator==(string const &) const { return false; } 40 | 41 | template constexpr 42 | string operator+(string const &) const { return {}; } 43 | 44 | template constexpr 45 | auto section(std::index_sequence) const 46 | { 47 | return string{}; 48 | } 49 | 50 | template constexpr 51 | auto section() const 52 | { 53 | return section(std::make_index_sequence{}); 54 | } 55 | 56 | constexpr char operator[](int index) const { return c_str[index]; } 57 | 58 | template 59 | constexpr bool contains(char value) const 60 | { 61 | if constexpr (I >= size) return false; 62 | else if (c_str[I] == value) return true; 63 | else return contains(value); 64 | } 65 | }; 66 | 67 | template struct is_compile_string { static constexpr bool value = false; }; 68 | 69 | template struct is_compile_string> { 70 | static constexpr bool value = true; 71 | }; 72 | } 73 | 74 | //string literal to string class 75 | template 76 | constexpr auto operator""_s() { 77 | return constexpr_string::string(Chars)...>{}; 78 | } 79 | 80 | //number to string class 81 | template 82 | constexpr auto operator""_s() { 83 | return constexpr_string::string{}; 84 | } 85 | -------------------------------------------------------------------------------- /include/format.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Bastien Penavayre 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | #pragma once 23 | #include "string.hpp" 24 | #include "tools.hpp" 25 | #include 26 | 27 | namespace constexpr_format 28 | { 29 | using namespace constexpr_string; 30 | 31 | template 32 | class format_string 33 | { 34 | template 35 | struct substring 36 | { 37 | template 38 | static constexpr auto parse(std::tuple const &t) { 39 | return String::instance.template 40 | section() + std::get(t); 41 | } 42 | }; 43 | 44 | template 45 | static constexpr bool is_number() 46 | { 47 | if constexpr (begin >= end) return false; 48 | else if constexpr ("0123456789"_s.contains(String::instance[begin])) return true; 49 | else return is_number(); 50 | } 51 | 52 | template 53 | static constexpr size_t get_index() 54 | { 55 | if constexpr (!is_number()) return index; 56 | else return atoi(); 57 | } 58 | 59 | template 60 | struct sublist 61 | { 62 | template 63 | using push_format = sublist<(max < index ? index : max), end, Args..., 64 | substring>; 65 | 66 | static constexpr size_t size = sizeof...(Args); 67 | static constexpr size_t Max = max; 68 | }; 69 | 70 | template > 71 | static constexpr auto parser() 72 | { 73 | if constexpr (I >= String::size) return Results{}; 74 | else 75 | { 76 | constexpr char c = String::instance[I]; 77 | if constexpr (!is_in) 78 | { 79 | if constexpr (c == '/') return parser(); 80 | else if constexpr (c == '{') return parser(); 81 | else return parser(); 82 | } 83 | else 84 | { 85 | if constexpr (c == '}') return parser() ? 0 : 1), 86 | typename Results::template push_format()>>(); 87 | else if constexpr (!" 0123456789"_s.contains(c)) return parser(); 88 | else return parser(); 89 | } 90 | } 91 | } 92 | 93 | static constexpr auto formats = parser(); 94 | 95 | template 96 | constexpr auto apply_args(sublist, std::tuple const &t) const 97 | { 98 | return (... + Formats::parse(t)) + String::instance.template section(); 99 | } 100 | 101 | public: 102 | 103 | template 104 | constexpr auto operator()(Args... args) const 105 | { 106 | static_assert((... && is_compile_string::value), 107 | "All argument must be compile-time strings"); 108 | static_assert(sizeof...(Args) >= formats.Max, "Not enough arguments"); 109 | return apply_args(formats, std::forward_as_tuple(args...)); 110 | } 111 | }; 112 | } 113 | 114 | template 115 | constexpr auto operator""_format() 116 | { 117 | using namespace constexpr_format; 118 | return format_string(Chars)...>>{}; 119 | } 120 | --------------------------------------------------------------------------------