qxLib
data.inl
Go to the documentation of this file.
1 /**
2 
3  @file data.inl
4  @author Khrapov
5  @date 13.08.2025
6  @copyright © Nick Khrapov, 2025. All right reserved.
7 
8 **/
9 
10 template<qx::arithmetic_c T>
11 class qx::convert<T, qx::units::data> : public units::details::base_converter<T, units::data>
12 {
13 public:
15 
16  constexpr unit<T, units::data> to(units::data eTo) const noexcept;
17 };
18 
19 template<>
20 struct std::formatter<qx::units::data, qx::char_type> : qx::basic_formatter
21 {
22  template<class format_context_type_t>
23  constexpr auto format(qx::units::data eData, format_context_type_t& ctx) const noexcept;
24 };
25 
26 namespace qx::units::details
27 {
28 
29 constexpr bool is_binary(data eDataSize) noexcept
30 {
31  return eDataSize < data::_last_binary;
32 }
33 
34 template<class T>
35 constexpr i64 to_bits(data eFrom, T value) noexcept
36 {
37  if (is_binary(eFrom))
38  {
39  return static_cast<i64>(static_cast<double>(value) * pow(2, static_cast<int>(eFrom)));
40  }
41  else
42  {
43  return static_cast<i64>(
44  8.f * static_cast<double>(value) * pow(10, static_cast<int>(eFrom) - static_cast<int>(data::_last_binary)));
45  }
46 }
47 
48 template<class T>
49 constexpr T from_bits(i64 bits, data eTo) noexcept
50 {
51  if (is_binary(eTo))
52  {
53  return static_cast<T>(static_cast<double>(bits) / pow(2, static_cast<int>(eTo)));
54  }
55  else
56  {
57  return static_cast<T>(
58  static_cast<double>(bits) / pow(10, static_cast<int>(eTo) - static_cast<int>(data::_last_binary)) / 8.f);
59  }
60 }
61 
62 template<arithmetic_c T>
63 struct unit_normalizer<T, data>
64 {
65  static constexpr unit<T, data> normalize(unit<T, data> unit) noexcept;
66 };
67 
68 template<class char_t>
69 struct unit_suffixes<data, char_t>
70 {
71  static constexpr auto get() noexcept
72  {
73  using pair_type = std::pair<data, basic_string_view<char_t>>;
74  return std::array { pair_type { data::bits, QX_STR_PREFIX(char_t, "b") },
75  pair_type { data::nibbles, QX_STR_PREFIX(char_t, "nib") },
76  pair_type { data::bytes, QX_STR_PREFIX(char_t, "B") },
77  pair_type { data::kibibytes, QX_STR_PREFIX(char_t, "KiB") },
78  pair_type { data::mebibytes, QX_STR_PREFIX(char_t, "MiB") },
79  pair_type { data::gibibytes, QX_STR_PREFIX(char_t, "GiB") },
80  pair_type { data::tebibytes, QX_STR_PREFIX(char_t, "TiB") },
81  pair_type { data::pebibytes, QX_STR_PREFIX(char_t, "PiB") },
82  pair_type { data::kilobytes, QX_STR_PREFIX(char_t, "kB") },
83  pair_type { data::megabytes, QX_STR_PREFIX(char_t, "MB") },
84  pair_type { data::gigabytes, QX_STR_PREFIX(char_t, "GB") },
85  pair_type { data::terabytes, QX_STR_PREFIX(char_t, "TB") },
86  pair_type { data::petabytes, QX_STR_PREFIX(char_t, "PB") } };
87  }
88 };
89 
90 } // namespace qx::units::details
91 
92 template<qx::arithmetic_c T>
93 constexpr qx::unit<T, qx::units::data> qx::convert<T, qx::units::data>::to(units::data eTo) const noexcept
94 {
95  if (this->m_From.type == eTo)
96  return { this->m_From.value, eTo };
97 
98  const i64 bits = units::details::to_bits(this->m_From.type, this->m_From.value);
99  return { units::details::from_bits<T>(bits, eTo), eTo };
100 }
101 
102 template<class format_context_type_t>
103 constexpr auto std::formatter<qx::units::data, qx::char_type>::format(qx::units::data eData, format_context_type_t& ctx)
104  const noexcept
105 {
106  auto out = ctx.out();
107 
109 
110  auto itName = std::ranges::find_if(
111  suffixes,
112  [eData](const std::pair<qx::units::data, qx::string_view>& pair)
113  {
114  return pair.first == eData;
115  });
116  if (itName != suffixes.end())
117  out = std::format_to(out, QX_TEXT("{}"), itName->second);
118 
119  return out;
120 }
121 
122 template<qx::arithmetic_c T>
124  unit<T, data> unit) noexcept
125 {
126  const i64 nBits = details::to_bits(unit.type, unit.value);
127  const f64 fAbsBits = static_cast<f64>(abs(nBits));
128 
129  data eTo = data::pebibytes;
130  if (fAbsBits <= pow(2, 3))
131  {
132  eTo = data::bits;
133  }
134  else if (fAbsBits <= pow(2, 13))
135  {
136  eTo = data::bytes;
137  }
138  else if (fAbsBits <= pow(2, 23))
139  {
140  eTo = data::kibibytes;
141  }
142  else if (fAbsBits <= pow(2, 33))
143  {
144  eTo = data::mebibytes;
145  }
146  else if (fAbsBits <= pow(2, 43))
147  {
148  eTo = data::gibibytes;
149  }
150  else if (fAbsBits <= pow(2, 53))
151  {
152  eTo = data::tebibytes;
153  }
154 
155  return convert(unit).to(eTo);
156 }
A conversion class.
Definition: base.h:62
constexpr T abs(T value)
Constexpr absolute value.
Definition: common.inl:14
constexpr double pow(T number, int nPower)
Power function for integer power.
Definition: common.inl:82
#define QX_STR_PREFIX(value_t, str)
Chose witch of prefixes add to string : L or none.
Definition: string_utils.h:249
Definition: base.h:38