8#ifndef BOOST_LOCALE_FORMAT_HPP_INCLUDED
9#define BOOST_LOCALE_FORMAT_HPP_INCLUDED
11#include <boost/locale/formatting.hpp>
12#include <boost/locale/hold_ptr.hpp>
13#include <boost/locale/message.hpp>
21# pragma warning(disable : 4275 4251 4231 4660)
24namespace boost {
namespace locale {
35 template<
typename CharType>
37 typedef std::basic_ostream<CharType> stream_type;
38 typedef void (*writer_type)(stream_type& output,
const void* ptr);
40 formattible() noexcept : pointer_(
nullptr), writer_(&formattible::void_write) {}
42 formattible(
const formattible&)
noexcept =
default;
43 formattible(formattible&&)
noexcept =
default;
44 formattible& operator=(
const formattible&)
noexcept =
default;
45 formattible& operator=(formattible&&)
noexcept =
default;
47 template<
typename Type>
48 explicit formattible(
const Type& value)
noexcept
50 pointer_ =
static_cast<const void*
>(&value);
51 writer_ = &write<Type>;
54 friend stream_type& operator<<(stream_type& out,
const formattible& fmt)
56 fmt.writer_(out, fmt.pointer_);
61 static void void_write(stream_type& output,
const void* )
63 CharType empty_string[1] = {0};
64 output << empty_string;
67 template<
typename Type>
68 static void write(stream_type& output,
const void* ptr)
70 output << *static_cast<const Type*>(ptr);
77 class BOOST_LOCALE_DECL format_parser {
79 format_parser(std::ios_base& ios,
void*,
void (*imbuer)(
void*,
const std::locale&));
81 format_parser(
const format_parser&) =
delete;
82 format_parser& operator=(
const format_parser&) =
delete;
84 unsigned get_position();
86 void set_one_flag(
const std::string& key,
const std::string& value);
88 template<
typename CharType>
89 void set_flag_with_str(
const std::string& key,
const std::basic_string<CharType>& value)
91 if(key ==
"ftime" || key ==
"strftime") {
93 ios_info::get(ios_).date_time_pattern(value);
99 void imbue(
const std::locale&);
180 template<
typename CharType>
182 int throw_if_params_bound()
const;
188 typedef detail::formattible<CharType> formattible_type;
206 message_((other.throw_if_params_bound(), std::move(other.message_))), format_(std::move(other.format_)),
207 translate_(other.translate_), parameters_count_(0)
211 other.throw_if_params_bound();
212 message_ = std::move(other.message_);
213 format_ = std::move(other.format_);
214 translate_ = other.translate_;
215 parameters_count_ = 0;
234 template<
typename Formattible>
237 add(formattible_type(
object));
244 std::basic_ostringstream<CharType> buffer;
259 format_output(out,
format);
265 format_guard(detail::format_parser& fmt) : fmt_(fmt), restored_(false) {}
276 try { restore(); }
catch(...) {}
281 detail::format_parser& fmt_;
293 const size_t size = sformat.size();
294 const CharType*
format = sformat.c_str();
295 for(
size_t pos = 0;
format[pos];) {
315 detail::format_parser fmt(out,
static_cast<void*
>(&out), &basic_format::imbue_locale);
317 format_guard guard(fmt);
323 bool use_svalue =
true;
325 key +=
static_cast<char>(c);
330 if(
format[pos] == quote) {
334 if(
format[pos] == quote) {
335 if(
format[pos + 1] == quote) {
349 while((c =
format[pos]) != 0 && c != comma && c != cbrk) {
350 svalue +=
static_cast<char>(c);
357 fmt.set_one_flag(key, svalue);
359 fmt.set_flag_with_str(key, value);
365 unsigned position = fmt.get_position();
366 out << get(position);
375 void add(
const formattible_type& param)
377 if(parameters_count_ >= base_params_)
378 ext_params_.push_back(param);
380 parameters_[parameters_count_] = param;
384 formattible_type get(
unsigned id)
const
386 if(
id >= parameters_count_)
387 return formattible_type();
388 else if(
id >= base_params_)
389 return ext_params_[
id - base_params_];
391 return parameters_[id];
394 static void imbue_locale(
void* ptr,
const std::locale& l) {
static_cast<stream_type*
>(ptr)->imbue(l); }
396 static constexpr unsigned base_params_ = 8;
402 formattible_type parameters_[base_params_];
403 unsigned parameters_count_;
404 std::vector<formattible_type> ext_params_;
410 template<
typename CharType>
411 std::basic_ostream<CharType>&
operator<<(std::basic_ostream<CharType>& out,
const basic_format<CharType>& fmt)
421#ifndef BOOST_LOCALE_NO_CXX20_STRING8
426#ifdef BOOST_LOCALE_ENABLE_CHAR16_T
431#ifdef BOOST_LOCALE_ENABLE_CHAR32_T
436 template<
typename CharType>
439 if(parameters_count_)
440 throw std::invalid_argument(
"Can't move a basic_format with bound parameters");
This class represents a message that can be converted to a specific locale message.
Definition: message.hpp:142
a smart pointer similar to std::unique_ptr but the underlying object has the same constness as the po...
Definition: hold_ptr.hpp:17
void domain_id(int)
Set special message domain identification.
static ios_info & get(std::ios_base &ios)
Get ios_info instance for specific stream object.
std::basic_ostream< CharType > & operator<<(std::basic_ostream< CharType > &out, const date_time &t)
Definition: date_time.hpp:724
string_type str() const
Translate message to a string in the default global locale, using default domain.
Definition: message.hpp:238