8#include "utils/StringUtils.hpp"
12#ifdef __cpp_lib_bit_cast
26#include "utils/debug/Debug.hpp"
31concept Integral = std::is_integral_v<T>;
34concept EnumConcept = std::is_enum_v<T>;
36template <
class From,
class To>
37concept ConvertibleTo = std::is_convertible_v<From, To> && requires {
static_cast<To>(std::declval<From>()); };
39template <
class T,
class U>
40concept Derived = std::is_base_of_v<U, T>;
42template <
class T,
class U>
43concept Extends = Derived<T, U>;
45template <
class T,
class U>
46concept BaseOf = Derived<U, T>;
50struct RemoveAllPointers
51 : std::conditional_t<std::is_pointer_v<T>, RemoveAllPointers<std::remove_pointer_t<T>>, std::type_identity<T>> {};
54template <
typename T>
using RemoveAllPointers =
typename detail::RemoveAllPointers<T>::type;
56template <
class... Ts>
struct Overloads : Ts... {
57 using Ts::operator()...;
60template <
class... Ts> Overloads(Ts...) -> Overloads<Ts...>;
62struct DXFeedEventListener {};
64struct DXEndpointStateChangeListener {};
66struct IpfPropertyChangeListener {};
68struct InstrumentProfileUpdateListener {};
70template <
typename... T>
constexpr void ignoreUnused(
const T &...) {
73constexpr inline auto is_constant_evaluated(
bool default_value =
false)
noexcept ->
bool {
74#ifdef __cpp_lib_is_constant_evaluated
75 ignoreUnused(default_value);
76 return std::is_constant_evaluated();
83template <
typename To,
typename From>
84constexpr To bit_cast(
const From &from)
86 requires(
sizeof(To) ==
sizeof(From))
89#ifdef __cpp_lib_bit_cast
90 if (is_constant_evaluated())
91 return std::bit_cast<To>(from);
95 std::memcpy(
static_cast<
void *>(&to), &from,
sizeof(to));
100enum class Tristate : std::uint8_t {
106template <
typename GraalList,
typename ElementWrapper>
struct GraalListUtils {
107 static std::ptrdiff_t calculateSize(std::ptrdiff_t initSize)
noexcept {
108 using ListType = GraalList;
109 using SizeType =
decltype(ListType::size);
115 if (initSize > std::numeric_limits<SizeType>::max()) {
116 return std::numeric_limits<SizeType>::max();
122 static void *newList(std::ptrdiff_t size) {
123 using ListType = GraalList;
124 using SizeType =
decltype(ListType::size);
125 using ElementType = std::remove_pointer_t<
decltype(ListType::elements)>;
127 auto *list =
new ListType{
static_cast<SizeType>(size),
nullptr};
130 return static_cast<
void *>(list);
133 list->elements =
new ElementType[size]{
nullptr};
138 static bool setElement(
void *graalList, std::ptrdiff_t elementIdx,
void *element)
noexcept {
139 using ListType = GraalList;
140 using SizeType =
decltype(ListType::size);
141 using ElementType = std::remove_pointer_t<
decltype(ListType::elements)>;
143 if (graalList ==
nullptr || elementIdx < 0 || elementIdx >= std::numeric_limits<SizeType>::max() ||
144 element ==
nullptr) {
148 static_cast<ListType *>(graalList)->elements[elementIdx] =
static_cast<ElementType>(element);
153 static bool freeElements(
void *graalList, std::ptrdiff_t count) {
154 using ListType = GraalList;
155 using SizeType =
decltype(ListType::size);
157 if (graalList ==
nullptr || count < 0 || count >= std::numeric_limits<SizeType>::max()) {
161 auto *list =
static_cast<ListType *>(graalList);
163 for (SizeType i = 0; i < count; i++) {
164 if (list->elements[i]) {
165 ElementWrapper::freeGraal(
static_cast<
void *>(list->elements[i]));
169 delete[] list->elements;
175 static void freeList(
void *graalList) {
176 using ListType = GraalList;
177 using SizeType =
decltype(ListType::size);
179 if (graalList ==
nullptr) {
183 auto list =
static_cast<ListType *>(graalList);
185 if (list->size > 0 && list->elements !=
nullptr) {
186 for (SizeType elementIndex = 0; elementIndex < list->size; elementIndex++) {
187 if (list->elements[elementIndex]) {
188 ElementWrapper::freeGraal(
static_cast<
void *>(list->elements[elementIndex]));
192 delete[] list->elements;
198 static std::vector<ElementWrapper> fromList(
void *graalList) {
199 using ListType = GraalList;
200 using SizeType =
decltype(ListType::size);
206 std::vector<ElementWrapper> result{};
208 auto list =
static_cast<ListType *>(graalList);
210 if (list->size > 0 && list->elements !=
nullptr) {
211 for (SizeType elementIndex = 0; elementIndex < list->size; elementIndex++) {
212 if (list->elements[elementIndex]) {
213 result.emplace_back(ElementWrapper::fromGraal(
static_cast<
void *>(list->elements[elementIndex])));
223
224
226 return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch())
231static constexpr std::int64_t floorDiv(std::int64_t x, std::int64_t y) {
232 std::int64_t r = x / y;
235 if ((x < 0) != (y < 0) && (r * y != x)) {
242static constexpr std::int64_t floorMod(std::int64_t x, std::int64_t y) {
243 return x - (floorDiv(x, y) * y);
246static const double NaN = std::numeric_limits<
double>::quiet_NaN();
248static bool equals(
double a,
double b,
double eps = std::numeric_limits<
double>::epsilon()) {
249 if (std::isnan(a) || std::isnan(b)) {
253 return std::abs(a - b) < eps;
256template <
typename T,
typename U>
static bool equals(T a, U b,
double eps = std::numeric_limits<
double>::epsilon()) {
257 if (std::isnan(
static_cast<
double>(a)) || std::isnan(
static_cast<
double>(b))) {
261 return std::abs(
static_cast<
double>(a) -
static_cast<
double>(b)) < eps;
266namespace time_nanos_util {
267static constexpr std::int64_t NANOS_IN_MILLIS = 1'000'000LL;
270
271
272
273
274
275
276
277static constexpr std::int64_t getNanosFromMillisAndNanoPart(std::int64_t timeMillis, std::int32_t timeNanoPart) {
278 return (timeMillis * NANOS_IN_MILLIS) + timeNanoPart;
282
283
284
285
286
287
288
289
290
291static constexpr std::int64_t getMillisFromNanos(std::int64_t timeNanos) {
292 return math::floorDiv(timeNanos, NANOS_IN_MILLIS);
296
297
298
299
300
301
302
303
304
305static constexpr std::int32_t getNanoPartFromNanos(std::int64_t timeNanos) {
306 return static_cast<std::int32_t>(math::floorMod(timeNanos, NANOS_IN_MILLIS));
313static constexpr std::int64_t SECOND = 1000LL;
316static constexpr std::int64_t MINUTE = 60LL * SECOND;
319static constexpr std::int64_t HOUR = 60LL * MINUTE;
322static constexpr std::int64_t DAY = 24LL * HOUR;
325
326
327
328
329
330
331static constexpr std::int32_t getMillisFromTime(std::int64_t timeMillis) {
332 return static_cast<std::int32_t>(math::floorMod(timeMillis, SECOND));
336
337
338
339
340
341
342static constexpr std::int32_t getSecondsFromTime(std::int64_t timeMillis) {
343 if (timeMillis >= 0) {
344 return static_cast<std::int32_t>(
345 std::min(timeMillis / SECOND,
static_cast<std::int64_t>(std::numeric_limits<std::int32_t>::max())));
348 return static_cast<std::int32_t>(
349 std::max((timeMillis + 1) / SECOND - 1,
static_cast<std::int64_t>(std::numeric_limits<std::int32_t>::min())));
356
357
358
359
360
361
362
363template <Integral T>
constexpr static T div(T a, T b) {
369 return ((a + 1) / b) - 1;
372 return ((a + 1) / b) + 1;
375template <Integral T>
constexpr static T abs(T a) {
376 return a < 0 ? -a : a;
384static std::int32_t DAY_OF_YEAR[] = {0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
388
389
390
391
392
393
394
395
396constexpr static std::int32_t getYearMonthDayByDayId(std::int32_t dayId) {
397 std::int32_t j = dayId + 2472632;
398 std::int32_t g = math_util::div(j, 146097);
399 std::int32_t dg = j - g * 146097;
400 std::int32_t c = (dg / 36524 + 1) * 3 / 4;
401 std::int32_t dc = dg - c * 36524;
402 std::int32_t b = dc / 1461;
403 std::int32_t db = dc - b * 1461;
404 std::int32_t a = (db / 365 + 1) * 3 / 4;
405 std::int32_t da = db - a * 365;
406 std::int32_t y = g * 400 + c * 100 + b * 4 +
408 std::int32_t m = (da * 5 + 308) / 153 -
411 da - (m + 4) * 153 / 5 + 122;
412 std::int32_t yyyy = y - 4800 + (m + 2) / 12;
413 std::int32_t mm = (m + 2) % 12 + 1;
414 std::int32_t dd = d + 1;
415 std::int32_t yyyymmdd = math_util::abs(yyyy) * 10000 + mm * 100 + dd;
417 return yyyy >= 0 ? yyyymmdd : -yyyymmdd;
420std::int32_t getDayIdByYearMonthDay(std::int32_t year, std::int32_t month, std::int32_t day);
425template <
typename...>
struct MaxImpl;
427template <
typename T>
struct MaxImpl<T> {
431template <
typename T,
typename U>
struct MaxImpl<T, U> {
432 using Type = std::conditional_t<
sizeof(T) >=
sizeof(U), T, U>;
435template <
typename T,
typename U,
typename V,
typename... Ws>
struct MaxImpl<T, U, V, Ws...> {
436 using Type =
typename MaxImpl<T,
typename MaxImpl<U,
typename MaxImpl<V, Ws...>::Type>::Type>::Type;
441
442
443template <
typename... Ts>
using Max =
typename detail::MaxImpl<Ts...>::Type;
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460template <Integral V, Integral S>
static constexpr V sar(V value, S shift)
noexcept;
463
464
465
466
467
468
469
470
471
472
473
474
475
476template <Integral V, Integral S>
static constexpr V leftArithmeticShift(V value, S shift)
noexcept {
477 if constexpr (std::is_signed_v<S>) {
479 return sar(value, -shift);
483 if (shift == 0 || value == 0) {
487 auto unsignedShift =
static_cast<std::make_unsigned_t<S>>(shift);
489 if (unsignedShift >=
sizeof(V) * CHAR_BIT) {
493 return value << unsignedShift;
497
498
499
500
501
502
503
504
505
506
507
508
509
510template <Integral V, Integral S>
static constexpr V sal(V value, S shift)
noexcept {
511 return leftArithmeticShift(value, shift);
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529template <Integral V, Integral S>
static constexpr V rightArithmeticShift(V value, S shift)
noexcept {
530 if constexpr (std::is_signed_v<S>) {
532 return sal(value, -shift);
536 if (shift == 0 || value == 0) {
540 auto unsignedShift =
static_cast<std::make_unsigned_t<S>>(shift);
542 if (unsignedShift >=
sizeof(V) * CHAR_BIT) {
543 return value < 0 ? -1 : 0;
546 return value >> unsignedShift;
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564template <Integral V, Integral S>
static constexpr V sar(V value, S shift)
noexcept {
565 return rightArithmeticShift(value, shift);
569
570
571
572
573
574
575
576
577
578
579
580
581
582template <Integral V, Integral S>
static constexpr V shr(V value, S shift)
noexcept;
585
586
587
588
589
590
591
592
593
594
595
596
597
598template <Integral V, Integral S>
static constexpr V leftLogicalShift(V value, S shift)
noexcept {
599 if constexpr (std::is_signed_v<S>) {
601 return shr(value, -shift);
605 if (shift == 0 || value == 0) {
609 auto unsignedShift =
static_cast<std::make_unsigned_t<S>>(shift);
611 if (unsignedShift >=
sizeof(V) * CHAR_BIT) {
615 return value << unsignedShift;
619
620
621
622
623
624
625
626
627
628
629
630
631
632template <Integral V, Integral S>
static constexpr V shl(V value, S shift)
noexcept {
633 return leftLogicalShift(value, shift);
637
638
639
640
641
642
643
644
645
646
647
648
649
650template <Integral V, Integral S>
static constexpr V rightLogicalShift(V value, S shift)
noexcept {
651 if constexpr (std::is_signed_v<S>) {
653 return shl(value, -shift);
657 if (shift == 0 || value == 0) {
661 auto unsignedShift =
static_cast<std::make_unsigned_t<S>>(shift);
663 if (unsignedShift >=
sizeof(V) * CHAR_BIT) {
667 return static_cast<V>(
static_cast<std::make_unsigned_t<V>>(value) >> unsignedShift);
671
672
673
674
675
676
677
678
679
680
681
682
683
684template <Integral V, Integral S>
static constexpr V shr(V value, S shift)
noexcept {
685 return rightLogicalShift(value, shift);
688template <Integral A, Integral B>
static constexpr A andOp(A a, B b)
noexcept {
689 using Common = std::make_unsigned_t<Max<A, B>>;
691 return static_cast<A>(
static_cast<Common>(a) &
static_cast<Common>(b));
694template <Integral A, Integral B>
static constexpr A orOp(A a, B b)
noexcept {
695 using Common = std::make_unsigned_t<Max<A, B>>;
697 return static_cast<A>(
static_cast<Common>(a) |
static_cast<Common>(b));
700template <Integral A, Integral B>
static constexpr A xorOp(A a, B b)
noexcept {
701 using Common = std::make_unsigned_t<Max<A, B>>;
703 return static_cast<A>(
static_cast<Common>(a) ^
static_cast<Common>(b));
706template <Integral F, Integral M, Integral S>
static constexpr F getBits(F flags, M mask, S shift)
noexcept {
707 return static_cast<F>(andOp(shr(flags, shift), mask));
710template <Integral T>
static constexpr T setBits(T flags, T mask, T shift, T bits)
noexcept {
711 if constexpr (std::is_signed_v<T>) {
712 using U = std::make_unsigned_t<T>;
714 return static_cast<T>((
static_cast<U>(flags) & ~(
static_cast<U>(mask) <<
static_cast<U>(shift))) |
715 ((
static_cast<U>(bits) &
static_cast<U>(mask)) <<
static_cast<U>(shift)));
717 return (flags & ~(mask << shift)) | ((bits & mask) << shift);
721template <Integral F, Integral M, Integral S, Integral B>
722static constexpr F setBits(F flags, M mask, S shift, B bits)
noexcept {
723 if constexpr (std::is_signed_v<F> || std::is_signed_v<M> || std::is_signed_v<S> || std::is_signed_v<B>) {
724 using U = std::make_unsigned_t<Max<F, M, S, B>>;
726 return static_cast<F>((
static_cast<U>(flags) & ~(
static_cast<U>(mask) <<
static_cast<U>(shift))) |
727 ((
static_cast<U>(bits) &
static_cast<U>(mask)) <<
static_cast<U>(shift)));
729 return (flags & ~(mask << shift)) | ((bits & mask) << shift);
733template <std::size_t Bits>
struct hashMixImpl;
735template <>
struct hashMixImpl<64> {
736 constexpr static std::uint64_t fn(std::uint64_t x)
noexcept {
737 std::uint64_t
const m = (
static_cast<std::uint64_t>(0xe9846af) << 32) + 0x9b1a615d;
749template <>
struct hashMixImpl<32> {
750 constexpr static std::uint32_t fn(std::uint32_t x)
noexcept {
751 std::uint32_t
const m1 = 0x21f0aaad;
752 std::uint32_t
const m2 = 0x735a2d97;
764constexpr static std::size_t hashMix(std::size_t v)
noexcept {
765 return hashMixImpl<
sizeof(std::size_t) * CHAR_BIT>::fn(v);
768template <
class T>
constexpr void hashCombine(std::size_t &seed,
const T &v)
noexcept {
769 seed = hashMix(seed + 0x9e3779b9 + std::hash<T>()(v));
772template <Integral T, Integral U>
constexpr std::size_t pack(T t, U u)
noexcept {
773 constexpr auto sizeOfSize =
sizeof(std::size_t) * CHAR_BIT;
775 return orOp(shl(t, sizeOfSize / 2), u);
778constexpr std::pair<std::size_t, std::size_t> unpack(std::size_t v)
noexcept {
779 constexpr auto sizeOfSize =
sizeof(std::size_t) * CHAR_BIT;
781 return {shr(v, sizeOfSize / 2), andOp(v, shr(~std::size_t{}, sizeOfSize / 2))};
784template <
typename T,
typename U> T fitToType(
const U &size) {
785 static_assert(
sizeof(T) <=
sizeof(U));
787 return static_cast<T>(
static_cast<U>(std::numeric_limits<T>::max()) < size ? std::numeric_limits<T>::max() : size);
791
792
793
801 StringLikeWrapper(std::string_view sv) : data_{sv} {
804 StringLikeWrapper(
const char *chars) : data_{chars ==
nullptr ? std::string_view{} : std::string_view{chars}} {
807 StringLikeWrapper(
const std::string &s) : data_{s} {
810 StringLikeWrapper(std::string &&s) : data_{std::move(s)} {
814 StringLikeWrapper(
const char (&chars)[N]) : StringLikeWrapper{std::string_view{chars, chars + N}} {
817 operator std::string()
const {
818 if (
auto sv = std::get_if<std::string_view>(&data_); sv) {
819 return {sv->data(), sv->size()};
821 return std::get<std::string>(data_);
833 const char *
data()
const {
841 const char *
c_str()
const {
896#ifdef _LIBCPP_VERSION
913 using is_transparent =
void;
915 std::size_t operator()(
const char *str)
const {
916 return HashType{}(str);
919 std::size_t operator()(std::string_view sw)
const {
920 return HashType{}(sw);
923 std::size_t operator()(std::string
const &str)
const {
924 return HashType{}(str);
928 return HashType{}(sw);
934void throwInvalidChar(
char c,
const std::string &name);
936inline void checkChar(
char c, std::uint32_t mask,
const std::string &name) {
937 if ((andOp(c, ~mask)) != 0) {
938 throwInvalidChar(c, name);
946template <Integral Type,
typename ResultType =
int> ResultType compare(Type v1, Type v2) {
958inline int compare(
double d1,
double d2) {
959 if (std::isnan(d1) || std::isnan(d2)) {
960 return std::isnan(d1) ? (std::isnan(d2) ? 0 : -1) : 1;
#define DXFCXX_DISABLE_MSC_WARNINGS_POP()
Definition Conf.hpp:22
#define DXFCPP_END_NAMESPACE
Definition Conf.hpp:70
#define DXFCPP_BEGIN_NAMESPACE
Definition Conf.hpp:67
#define DXFCXX_DISABLE_GCC_WARNINGS_PUSH(warnings)
Definition Conf.hpp:38
#define DXFCXX_DISABLE_GCC_WARNINGS_POP()
Definition Conf.hpp:40
#define DXFCXX_DISABLE_MSC_WARNINGS_PUSH(warnings)
Definition Conf.hpp:21
#define DXFCPP_EXPORT
Definition api.h:35
Base abstract class for all dxFeed C++ API entities.
Definition Entity.hpp:13
Marks all event types that can be received via dxFeed API.
Definition EventType.hpp:31
A helper class needed to construct smart pointers to objects, and does not allow explicit constructio...
Definition SharedEntity.hpp:89
static auto createShared(Args &&...args)
Creates smart pointer to object.
Definition SharedEntity.hpp:103
Base abstract "shared entity" class. Has some helpers for dynamic polymorphism.
Definition SharedEntity.hpp:21
virtual std::string toString() const
Returns a string representation of the current object.
Definition SharedEntity.hpp:78
std::shared_ptr< T > sharedAs() const noexcept
Returns a pointer to the current object wrapped in a smart pointer to type T.
Definition SharedEntity.hpp:69
std::shared_ptr< T > sharedAs() noexcept
Returns a pointer to the current object wrapped in a smart pointer to type T.
Definition SharedEntity.hpp:56
bool is() const noexcept
Checks that pointer to the current type could be converted to type T* In other words: whether type T ...
Definition SharedEntity.hpp:35
Universal functional object that allows searching std::unordered_map for string-like keys.
Definition Common.hpp:911
A simple wrapper around strings or something similar to strings to reduce the amount of code for meth...
Definition Common.hpp:794