sparrow 0.9.0
Loading...
Searching...
No Matches
large_int.hpp
Go to the documentation of this file.
1// Copyright 2024 Man Group Operations Limited
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or mplied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#pragma once
16
17#ifndef SPARROW_USE_LARGE_INT_PLACEHOLDERS
18
19// disabe warnings -Wold-style-cast sign-conversion for clang and gcc
20# if defined(__clang__) || defined(__GNUC__)
21# pragma GCC diagnostic push
22# pragma GCC diagnostic ignored "-Wold-style-cast"
23# pragma GCC diagnostic ignored "-Wsign-conversion"
24# pragma GCC diagnostic ignored "-Wshadow"
25# endif
26# include <sparrow/details/3rdparty/large_integers/int128_t.hpp>
27# include <sparrow/details/3rdparty/large_integers/int256_t.hpp>
28
29# if defined(__clang__) || defined(__GNUC__)
30# pragma GCC diagnostic pop
31# endif
32
33#endif
34
35#include <cstdint>
36#include <type_traits>
37
38namespace sparrow
39{
40#ifdef SPARROW_USE_LARGE_INT_PLACEHOLDERS
41 constexpr bool large_int_placeholders = true;
42
43 struct int128_t
44 {
45 int128_t() = default;
46
47 std::uint64_t words[2];
48
49 bool operator==(const int128_t& other) const
50 {
51 return words[0] == other.words[0] && words[1] == other.words[1];
52 }
53
54 bool operator!=(const int128_t& other) const
55 {
56 return !(*this == other);
57 }
58 };
59
60 struct int256_t
61 {
62 int256_t() = default;
63 std::uint64_t words[4];
64
65 bool operator==(const int256_t& other) const
66 {
67 return words[0] == other.words[0] && words[1] == other.words[1] && words[2] == other.words[2]
68 && words[3] == other.words[3];
69 }
70
71 bool operator!=(const int256_t& other) const
72 {
73 return !(*this == other);
74 }
75 };
76 template <class T>
77 constexpr bool is_int_placeholder_v = std::is_same_v<T, int128_t> || std::is_same_v<T, int256_t>;
78
79#else
80
81 template <class T>
82 constexpr bool is_int_placeholder_v = false;
83 constexpr bool large_int_placeholders = false;
84 using int128_t = primesum::int128_t;
85 using int256_t = primesum::int256_t;
86
87 template <typename T>
88 T stobigint(std::string_view str)
89 {
90 if (str.empty())
91 {
92 return 0;
93 }
94 T digits = 0;
95 bool negative = false;
96 for (auto it = str.begin(); it != str.end(); ++it)
97 {
98 if (*it == '-')
99 {
100 if (it == str.begin())
101 {
102 negative = true;
103 continue;
104 }
105 else
106 {
107 throw std::invalid_argument("Invalid character in string for conversion to large integer");
108 }
109 }
110 else if (*it < '0' || *it > '9')
111 {
112 throw std::invalid_argument("Invalid character in string for conversion to large integer");
113 }
114 digits *= 10;
115 digits += T(*it - '0');
116 }
117 if (negative)
118 {
119 digits *= -1;
120 }
121 return digits;
122 }
123
124#endif
125} // namespace sparrow
126
127#if defined(__cpp_lib_format)
128
129# include <format>
130
131// Full specialization fails on OSX 15.4 because the
132// template is already instantiated in std::format
133// implementation
134template <class charT>
135struct std::formatter<sparrow::int128_t, charT>
136{
137 template <class ParseContext>
138 constexpr ParseContext::iterator parse(ParseContext& ctx)
139 {
140 return ctx.begin(); // Simple implementation
141 }
142
143 template <class FmtContext>
144 FmtContext::iterator format(const sparrow::int128_t& n, FmtContext& ctx) const
145 {
146# ifdef SPARROW_USE_LARGE_INT_PLACEHOLDERS
147 return std::format_to(ctx.out(), "int128_t({}, {})", n.words[0], n.words[1]);
148# else
149 const std::string str = primesum::to_string(n);
150 return std::format_to(ctx.out(), "{}", str);
151# endif
152 }
153};
154
155template <class charT>
156struct std::formatter<sparrow::int256_t, charT>
157{
158 template <class ParseContext>
159 constexpr ParseContext::iterator parse(ParseContext& ctx)
160 {
161 return ctx.begin(); // Simple implementation
162 }
163
164 template <class FmtContext>
165 FmtContext::iterator format(const sparrow::int256_t& n, FmtContext& ctx) const
166 {
167# ifdef SPARROW_USE_LARGE_INT_PLACEHOLDERS
168 return std::format_to(ctx.out(), "int256_t({}, {}, {}, {})", n.words[0], n.words[1], n.words[2], n.words[3]);
169# else
170 const std::string str = primesum::to_string(n);
171 return std::format_to(ctx.out(), "{}", str);
172# endif
173 }
174};
175
176#endif
primesum::int128_t int128_t
Definition large_int.hpp:84
SPARROW_API bool operator==(const array &lhs, const array &rhs)
Compares the content of two arrays.
constexpr bool is_int_placeholder_v
Definition large_int.hpp:82
constexpr bool large_int_placeholders
Definition large_int.hpp:83
primesum::int256_t int256_t
Definition large_int.hpp:85
T stobigint(std::string_view str)
Definition large_int.hpp:88