1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
#pragma once
#include "pre_config.hpp"
#include <sstream>
#include <string>
#include <string_view>
namespace cru::util {
namespace details {
template <typename T>
struct FormatTrait {};
template <>
struct FormatTrait<std::string_view> {
static constexpr std::string_view placeholder = "{}";
using ResultType = std::string;
using StreamType = std::stringstream;
};
template <>
struct FormatTrait<std::wstring_view> {
static constexpr std::wstring_view placeholder = L"{}";
using ResultType = std::wstring;
using StreamType = std::wstringstream;
};
template <typename TStringView>
void FormatInternal(typename FormatTrait<TStringView>::StreamType& stream,
const TStringView& string) {
const auto find_result = string.find(FormatTrait<TStringView>::placeholder);
if (find_result != TStringView::npos)
throw std::invalid_argument("There is more placeholders than args.");
stream << string;
}
template <typename TStringView, typename T, typename... TRest>
void FormatInternal(typename FormatTrait<TStringView>::StreamType& stream,
const TStringView& string, const T& arg,
const TRest&... args) {
const auto find_result = string.find(FormatTrait<TStringView>::placeholder);
if (find_result == TStringView::npos)
throw std::invalid_argument("There is less placeholders than args.");
stream << string.substr(0, find_result);
stream << arg;
FormatInternal(stream, string.substr(find_result + 2), args...);
}
template <typename TStringView, typename... T>
auto FormatTemplate(const TStringView& format, const T&... args) ->
typename FormatTrait<TStringView>::ResultType {
typename FormatTrait<TStringView>::StreamType stream;
FormatInternal(stream, format, args...);
return stream.str();
}
} // namespace details
template <typename... T>
std::wstring Format(const std::wstring_view& format, const T&... args) {
return details::FormatTemplate(format, args...);
}
template <typename... T>
std::string Format(const std::string_view& format, const T&... args) {
return details::FormatTemplate(format, args...);
}
} // namespace cru::util
|