fb-cpp 0.0.2
A modern C++ wrapper for the Firebird database API
Loading...
Searching...
No Matches
types.h
1/*
2 * MIT License
3 *
4 * Copyright (c) 2025 Adriano dos Santos Fernandes
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24
25#ifndef FBCPP_TYPES_H
26#define FBCPP_TYPES_H
27
28#include "fb-api.h"
29#include "config.h"
30#include <chrono>
31#include <cstdint>
32#include <format>
33#include <iostream>
34#include <string>
35#include <type_traits>
36
37#if FB_CPP_USE_BOOST_MULTIPRECISION != 0
38#include <boost/multiprecision/cpp_int.hpp>
39#include <boost/multiprecision/cpp_dec_float.hpp>
40#endif
41
42#if FB_CPP_USE_BOOST_DECIMAL != 0
43#include <boost/decimal.hpp>
44#endif
45
46
50namespace fbcpp
51{
55 template <typename T>
56 struct ScaledNumber final
57 {
58 bool operator==(const ScaledNumber& o) const noexcept
59 {
60 if constexpr (std::is_same_v<T, FB_I128>)
61 {
62 return value.fb_data[0] == o.value.fb_data[0] && value.fb_data[1] == o.value.fb_data[1] &&
63 scale == o.scale;
64 }
65 else
66 return value == o.value && scale == o.scale;
67 }
68
72 T value{};
73
77 int scale = 0;
78 };
79
84
89
94
95#if FB_CPP_USE_BOOST_MULTIPRECISION != 0
99 using BoostInt128 = boost::multiprecision::int128_t;
100
105#endif
106
107#if FB_CPP_USE_BOOST_MULTIPRECISION != 0
111 using BoostDecFloat16 = boost::multiprecision::number<boost::multiprecision::cpp_dec_float<16>>;
112
116 using BoostDecFloat34 = boost::multiprecision::number<boost::multiprecision::cpp_dec_float<34>>;
117#endif
118
119#if FB_CPP_USE_BOOST_DECIMAL != 0
123 using BoostDecimal32 = boost::decimal::decimal32_t;
124
128 using BoostDecimal64 = boost::decimal::decimal64_t;
129
133 using BoostDecimal128 = boost::decimal::decimal128_t;
134#endif
135
139 using Date = std::chrono::year_month_day;
140
144 using Time = std::chrono::hh_mm_ss<std::chrono::microseconds>;
145
149 struct Timestamp final
150 {
151 bool operator==(const Timestamp& o) const noexcept
152 {
153 return date == o.date && time.to_duration() == o.time.to_duration();
154 }
155
161 std::chrono::local_time<std::chrono::microseconds> toLocalTime() const noexcept
162 {
163 return std::chrono::local_days{date} + time.to_duration();
164 }
165
169 static Timestamp fromLocalTime(std::chrono::local_time<std::chrono::microseconds> value) noexcept
170 {
171 const auto days = std::chrono::floor<std::chrono::days>(value);
172 const Date dateValue{days};
173 const auto timeOfDay = std::chrono::duration_cast<std::chrono::microseconds>(value - days);
174
175 return Timestamp{dateValue, Time{timeOfDay}};
176 }
177
182
186 Time time{std::chrono::microseconds::zero()};
187 };
188
192 struct TimeTz final
193 {
194 bool operator==(const TimeTz& o) const noexcept
195 {
196 return utcTime.to_duration() == o.utcTime.to_duration() && zone == o.zone;
197 }
198
203
207 std::string zone;
208 };
209
213 struct TimestampTz final
214 {
215 bool operator==(const TimestampTz&) const noexcept = default;
216
221
225 std::string zone;
226 };
227
231 using OpaqueInt128 = FB_I128;
232
236 using OpaqueDecFloat16 = FB_DEC16;
237
241 using OpaqueDecFloat34 = FB_DEC34;
242
247
251 struct alignas(alignof(ISC_DATE)) OpaqueDate final
252 {
253 bool operator==(const OpaqueDate&) const noexcept = default;
254
258 ISC_DATE value;
259 };
260
264 struct alignas(alignof(ISC_TIME)) OpaqueTime final
265 {
266 bool operator==(const OpaqueTime&) const noexcept = default;
267
271 ISC_TIME value;
272 };
273
277 struct alignas(alignof(ISC_TIMESTAMP)) OpaqueTimestamp final
278 {
279 bool operator==(const OpaqueTimestamp& o) const noexcept
280 {
281 return value.timestamp_date == o.value.timestamp_date && value.timestamp_time == o.value.timestamp_time;
282 }
283
287 ISC_TIMESTAMP value;
288 };
289
293 struct alignas(alignof(ISC_TIME_TZ)) OpaqueTimeTz final
294 {
295 bool operator==(const OpaqueTimeTz& o) const noexcept
296 {
297 return value.utc_time == o.value.utc_time && value.time_zone == o.value.time_zone;
298 }
299
303 ISC_TIME_TZ value;
304 };
305
309 struct alignas(alignof(ISC_TIMESTAMP_TZ)) OpaqueTimestampTz final
310 {
311 bool operator==(const OpaqueTimestampTz& o) const noexcept
312 {
313 return value.utc_timestamp.timestamp_date == o.value.utc_timestamp.timestamp_date &&
314 value.utc_timestamp.timestamp_time == o.value.utc_timestamp.timestamp_time &&
315 value.time_zone == o.value.time_zone;
316 }
317
321 ISC_TIMESTAMP_TZ value;
322 };
323
324 // FIXME: test
328 template <typename T>
329 std::ostream& operator<<(std::ostream& os, const fbcpp::ScaledNumber<T>& scaledNumber)
330 {
331 os << scaledNumber.value << "e" << scaledNumber.scale;
332 return os;
333 }
334} // namespace fbcpp
335
336
337// FIXME: test
341template <typename T>
342struct std::formatter<fbcpp::ScaledNumber<T>> : std::formatter<T>
343{
347 constexpr auto parse(format_parse_context& ctx)
348 {
349 return std::formatter<T>::parse(ctx);
350 }
351
355 template <typename FormatContext>
356 auto format(const fbcpp::ScaledNumber<T>& scaledNumber, FormatContext& ctx) const
357 {
358 const auto valueEnd = std::formatter<T>::format(scaledNumber.value, ctx);
359 return std::format_to(valueEnd, "e{}", scaledNumber.scale);
360 }
361};
362
363
364#endif // FBCPP_TYPES_H
fb-cpp namespace.
Definition Attachment.h:46
std::ostream & operator<<(std::ostream &os, const fbcpp::ScaledNumber< T > &scaledNumber)
Stream insertion helper that renders the scaled number as value followed by e and the scale.
Definition types.h:329
boost::multiprecision::number< boost::multiprecision::cpp_dec_float< 34 > > BoostDecFloat34
34-digit decimal floating point using Boost.Multiprecision.
Definition types.h:116
FB_DEC16 OpaqueDecFloat16
Opaque 16-digit decimal floating point exposed by the Firebird API.
Definition types.h:236
boost::multiprecision::number< boost::multiprecision::cpp_dec_float< 16 > > BoostDecFloat16
16-digit decimal floating point using Boost.Multiprecision.
Definition types.h:111
boost::decimal::decimal128_t BoostDecimal128
34-digit decimal floating point using Boost.Decimal.
Definition types.h:133
boost::decimal::decimal32_t BoostDecimal32
7-digit decimal floating point using Boost.Decimal.
Definition types.h:123
FB_I128 OpaqueInt128
Opaque 128-bit integer exposed by the Firebird API.
Definition types.h:231
std::chrono::year_month_day Date
Firebird SQL calendar date.
Definition types.h:139
FB_DEC34 OpaqueDecFloat34
Opaque 34-digit decimal floating point exposed by the Firebird API.
Definition types.h:241
boost::multiprecision::int128_t BoostInt128
128-bit integer using Boost.Multiprecision.
Definition types.h:99
boost::decimal::decimal64_t BoostDecimal64
16-digit decimal floating point using Boost.Decimal.
Definition types.h:128
std::chrono::hh_mm_ss< std::chrono::microseconds > Time
Firebird SQL time-of-day with microsecond resolution.
Definition types.h:144
Wrapper for Firebird date values.
Definition types.h:252
ISC_DATE value
Raw Firebird date representation.
Definition types.h:258
Wrapper for Firebird time-with-time-zone values.
Definition types.h:294
ISC_TIME_TZ value
Raw Firebird time-with-time-zone representation.
Definition types.h:303
Wrapper for Firebird time values.
Definition types.h:265
ISC_TIME value
Raw Firebird time representation.
Definition types.h:271
Wrapper for Firebird timestamp-with-time-zone values.
Definition types.h:310
ISC_TIMESTAMP_TZ value
Raw Firebird timestamp-with-time-zone representation.
Definition types.h:321
Wrapper for Firebird timestamp values.
Definition types.h:278
ISC_TIMESTAMP value
Raw Firebird timestamp representation.
Definition types.h:287
Represents a numeric value with an explicit decimal scale.
Definition types.h:57
int scale
Decimal scale applied to value.
Definition types.h:77
T value
Unscaled numeric value.
Definition types.h:72
Local time bound to a time zone.
Definition types.h:193
Time utcTime
UTC-normalised time-of-day.
Definition types.h:202
std::string zone
Time zone identifier.
Definition types.h:207
Timestamp bound to a time zone.
Definition types.h:214
Timestamp utcTimestamp
UTC-normalised timestamp.
Definition types.h:220
std::string zone
Time zone identifier.
Definition types.h:225
Combined date and time with microsecond precision.
Definition types.h:150
std::chrono::local_time< std::chrono::microseconds > toLocalTime() const noexcept
Converts to std::chrono::local_time<std::chrono::microseconds>.
Definition types.h:161
Time time
Time-of-day component.
Definition types.h:186
Date date
Calendar date component.
Definition types.h:181
static Timestamp fromLocalTime(std::chrono::local_time< std::chrono::microseconds > value) noexcept
Builds a timestamp from a local-time value.
Definition types.h:169
auto format(const fbcpp::ScaledNumber< T > &scaledNumber, FormatContext &ctx) const
Emits the scaled number using the native formatter for the value followed by the scale suffix.
Definition types.h:356
constexpr auto parse(format_parse_context &ctx)
Parses the format specifier forwarded to the underlying formatter.
Definition types.h:347