xtd 0.2.0
Loading...
Searching...
No Matches
__floating_point_formatter.h
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
10#include "__binary_formatter.h"
13#include "__format_exception.h"
15#include "__natural_formatter.h"
16#include "__sprintf.h"
17#include <algorithm>
18#include <cstring>
19#include <vector>
20
22template<typename char_t, typename value_t>
23inline std::basic_string<char_t> __floating_point_formatter(const std::basic_string<char_t>& format, value_t value, const std::locale& loc) {
24 auto fmt = format;
25 if (fmt.empty()) fmt = {'G'};
26
27 std::vector<char_t> possible_formats {'b', 'B', 'c', 'C', 'e', 'E', 'f', 'F', 'g', 'G', 'n', 'N', 'p', 'P', 'x', 'X'};
28 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])))
29 __format_exception("Custom format not yet implemented");
30
31 int precision = 0;
32 try {
33 if (fmt.size() > 1) precision = std::stoi(fmt.substr(1));
34 } catch (...) {
35 __format_exception("Invalid format expression");
36 }
37 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;
38 if ((fmt[0] == 'e' || fmt[0] == 'E') && fmt.size() == 1) precision = 6;
39 if ((fmt[0] == 'g' || fmt[0] == 'G') && fmt.size() == 1) precision = sizeof(value) <= 4 ? 7 : 15;
40
41 std::basic_string<char_t> fmt_str({'%', '.', '*', 'L'});
42 switch (fmt[0]) {
43 case 'b':
44 case 'B': {double value_double = static_cast<double>(value); int64_t value_int64 = 0; memcpy(&value_int64, &value_double, sizeof(value_double)); return __binary_formatter<char_t>(value_int64, precision);}
45 case 'c':
46 case 'C': return __currency_formatter<char_t>(static_cast<long double>(value), loc);
47 case 'e':
48 case 'E':
49 case 'f':
50 case 'F':
51 case 'g':
52 case 'G': return __sprintf((fmt_str + fmt[0]).c_str(), precision, static_cast<long double>(value));
53 case 'n':
54 case 'N': return __natural_formatter<char_t>(static_cast<long double>(value), precision, loc);
55 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('%')});
56 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('%')});
57 case 'x':
58 case 'X': return __hexfloat_formatter<char_t>(static_cast<long double>(value), precision, loc);
59 default: __format_exception("Invalid format expression"); return {};
60 }
61}
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.