Skip to content

Commit

Permalink
Add haxfloat formater
Browse files Browse the repository at this point in the history
  • Loading branch information
gammasoft71 committed Aug 3, 2024
1 parent 665b240 commit 42faa9e
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 1 deletion.
2 changes: 2 additions & 0 deletions src/xtd.core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,8 @@ add_sources(
include/xtd/internal/__format_stringer
include/xtd/internal/__hasher.h
include/xtd/internal/__hasher
include/xtd/internal/__hexfloat_formatter.h
include/xtd/internal/__hexfloat_formatter
include/xtd/internal/__iformatable_formatter.h
include/xtd/internal/__iformatable_formatter
include/xtd/internal/__natural_formatter.h
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@
#endif
/// @endcond

#include "__binary_formatter.h"
#include "__character_formatter.h"
#include "__currency_formatter.h"
#include "__format_exception.h"
#include "__hexfloat_formatter.h"
#include "__natural_formatter.h"
#include "__sprintf.h"
#include <algorithm>
Expand All @@ -21,7 +23,7 @@ inline std::basic_string<char_t> __floating_point_formatter(const std::basic_str
auto fmt = format;
if (fmt.empty()) fmt = {'G'};

std::vector<char_t> possible_formats {'c', 'C', 'e', 'E', 'f', 'F', 'g', 'G', 'n', 'N', 'p', 'P'};
std::vector<char_t> possible_formats {'b', 'B', 'c', 'C', 'e', 'E', 'f', 'F', 'g', 'G', 'n', 'N', 'p', 'P', 'x', 'X'};
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])))
__format_exception("Custom format not yet implemented");

Expand All @@ -37,6 +39,8 @@ inline std::basic_string<char_t> __floating_point_formatter(const std::basic_str

std::basic_string<char_t> fmt_str({'%', '.', '*', 'L'});
switch (fmt[0]) {
case 'b':
case 'B': {long double value_long_double = static_cast<long double>(value); int64_t value_int64 = 0; memcpy(&value_int64, &value_long_double, sizeof(value_long_double)); return __binary_formatter<char_t>(value_int64, precision);}
case 'c':
case 'C': return __currency_formatter<char_t>(static_cast<long double>(value), loc);
case 'e':
Expand All @@ -49,6 +53,8 @@ inline std::basic_string<char_t> __floating_point_formatter(const std::basic_str
case 'N': return __natural_formatter<char_t>(static_cast<long double>(value), precision, loc);
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('%')});
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('%')});
case 'x':
case 'X': return __hexfloat_formatter<char_t>(static_cast<long double>(value), precision, loc);
default: __format_exception("Invalid format expression"); return {};
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/xtd.core/include/xtd/internal/__hexfloat_formatter
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#pragma once
#include "__hexfloat_formatter.h"
23 changes: 23 additions & 0 deletions src/xtd.core/include/xtd/internal/__hexfloat_formatter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/// @file
/// @brief Contains __hexfloat_formatter method.
#pragma once
/// @cond
#if !defined(__XTD_CORE_INTERNAL__)
#error "Do not include this file: Internal use only"
#endif
/// @endcond

#include <iomanip>
#include <locale>
#include <string>
#include <sstream>

/// @cond
template<typename char_t>
inline std::basic_string<char_t> __hexfloat_formatter(long double value, int precision, const std::locale& loc) {
std::basic_stringstream<char_t> ss;
ss.imbue(loc);
ss << std::hexfloat << std::setprecision(precision) << value;
return ss.str();
}
/// @endcond

0 comments on commit 42faa9e

Please sign in to comment.