xtd 0.2.0
Loading...
Searching...
No Matches
__floating_point_formatter.hpp
Go to the documentation of this file.
1
3#pragma once
5#if !defined(__XTD_CORE_INTERNAL__)
6#error "Do not include this file: Internal use only"
7#endif
9
16#include "__sprintf.hpp"
17#include <algorithm>
18#include <cstring>
19#include <vector>
20
22template <typename char_t, typename floating_point_t>
23inline std::basic_string<char_t> __floating_point_to_binary(floating_point_t value, int precision) {
24 union {
25 double input;
26 int64_t output;
27 } data;
28 data.input = value;
29 return __binary_formatter<char_t>(data.output, precision);
30}
31
32template <>
33inline std::basic_string<char> __floating_point_to_binary<char, long double>(long double value, int precision) {
34 union {
35 long double input;
36 int64_t output;
37 } data;
38 data.input = value;
39 return __binary_formatter<char>(data.output, precision);
40}
41
42template <>
43inline std::basic_string<wchar_t> __floating_point_to_binary<wchar_t, long double>(long double value, int precision) {
44 union {
45 long double input;
46 int64_t output;
47 } data;
48 data.input = value;
49 return __binary_formatter<wchar_t>(data.output, precision);
50}
51
52template <>
53inline std::basic_string<char> __floating_point_to_binary<char, double>(double value, int precision) {
54 union {
55 double input;
56 int64_t output;
57 } data;
58 data.input = value;
59 return __binary_formatter<char>(data.output, precision);
60}
61
62template <>
63inline std::basic_string<wchar_t> __floating_point_to_binary<wchar_t, double>(double value, int precision) {
64 union {
65 double input;
66 int64_t output;
67 } data;
68 data.input = value;
69 return __binary_formatter<wchar_t>(data.output, precision);
70}
71
72template <>
73inline std::basic_string<char> __floating_point_to_binary<char, float>(float value, int precision) {
74 union {
75 float input;
76 int32_t output;
77 } data;
78 data.input = value;
79 return __binary_formatter<char>(data.output, precision);
80}
81
82template <>
83inline std::basic_string<wchar_t> __floating_point_to_binary<wchar_t, float>(float value, int precision) {
84 union {
85 float input;
86 int32_t output;
87 } data;
88 data.input = value;
89 return __binary_formatter<wchar_t>(data.output, precision);
90}
91
92template <typename char_t, typename value_t>
93inline std::basic_string<char_t> __floating_point_formatter(const std::basic_string<char_t>& format, value_t value, const std::locale& loc) {
94 auto fmt = format;
95 if (fmt.empty()) fmt = {'G'};
96
97 std::vector<char_t> possible_formats {'b', 'B', 'c', 'C', 'e', 'E', 'f', 'F', 'g', 'G', 'n', 'N', 'p', 'P', 'x', 'X'};
98 if (fmt.size() > 3 || std::find(possible_formats.begin(), possible_formats.end(), fmt[0]) == possible_formats.end() || (fmt.size() >= 2 && !std::isdigit(fmt[1])) || (fmt.size() == 3 && !std::isdigit(fmt[2])))
99 __format_exception("Custom format not yet implemented");
100
101 int precision = 0;
102 try {
103 if (fmt.size() > 1) precision = std::stoi(fmt.substr(1));
104 } catch (...) {
105 __format_exception("Invalid format expression");
106 }
107 if ((fmt[0] == 'f' || fmt[0] == 'F' || fmt[0] == 'n' || fmt[0] == 'N' || fmt[0] == 'p' || fmt[0] == 'P' || fmt[0] == 'r' || fmt[0] == 'R') && fmt.size() == 1) precision = 2;
108 if ((fmt[0] == 'e' || fmt[0] == 'E') && fmt.size() == 1) precision = 6;
109 if ((fmt[0] == 'g' || fmt[0] == 'G') && fmt.size() == 1) precision = sizeof(value) <= 4 ? 7 : 15;
110
111 std::basic_string<char_t> fmt_str({'%', '.', '*', 'L'});
112 switch (fmt[0]) {
113 case 'b':
114 case 'B': return __floating_point_to_binary<char_t>(value, precision);
115 case 'c':
116 case 'C': return __currency_formatter<char_t>(static_cast<long double>(value), loc);
117 case 'e':
118 case 'E':
119 case 'f':
120 case 'F':
121 case 'g':
122 case 'G': return __sprintf((fmt_str + fmt[0]).c_str(), precision, static_cast<long double>(value));
123 case 'n':
124 case 'N': return __natural_formatter<char_t>(static_cast<long double>(value), precision, loc);
125 case 'p': return __sprintf((fmt_str + char_t('f')).c_str(), precision, static_cast<long double>(value * 100)) + std::basic_string<char_t>({char_t(' '), char_t('%')});
126 case 'P': return __sprintf((fmt_str + char_t('F')).c_str(), precision, static_cast<long double>(value * 100)) + std::basic_string<char_t>({char_t(' '), char_t('%')});
127 case 'x':
128 case 'X': return __hexfloat_formatter<char_t>(static_cast<long double>(value), precision, loc);
129 default: __format_exception("Invalid format expression"); return {};
130 }
131}
Contains __binary_formatter method.
Contains __character_formatter method.
Contains __currency_formatter method.
Contains throw format exception method.
Contains __hexfloat_formatter method.
Contains __natural_formatter method.
Contains __format method.
xtd::string format(const xtd::string &fmt, args_t &&... args)
Writes the text representation of the specified arguments list, to string using the specified format ...
Definition format.hpp:20