50#ifndef OR_TOOLS_UTIL_STRONG_INTEGERS_H_
51#define OR_TOOLS_UTIL_STRONG_INTEGERS_H_
60#include "absl/base/attributes.h"
61#include "absl/base/port.h"
62#include "absl/strings/str_format.h"
63#include "absl/strings/string_view.h"
71#define DEFINE_STRONG_INDEX_TYPE(index_type_name) \
72 struct index_type_name##_index_tag_ { \
73 static constexpr absl::string_view TypeName() { return #index_type_name; } \
75 typedef ::operations_research::StrongIndex<index_type_name##_index_tag_> \
82#define DEFINE_STRONG_INT64_TYPE(integer_type_name) \
83 struct integer_type_name##_integer_tag_ { \
84 static constexpr absl::string_view TypeName() { \
85 return #integer_type_name; \
88 typedef ::operations_research::StrongInt64<integer_type_name##_integer_tag_> \
98#define STRONG_ASSIGNMENT_OP(StrongClass, IntType, op) \
99 ThisType& operator op(const ThisType & arg_value) { \
100 value_ op arg_value.value(); \
103 ThisType& operator op(IntType arg_value) { \
104 value_ op arg_value; \
108#define INCREMENT_AND_DECREMENT_OPERATORS \
109 ThisType& operator++() { \
113 const ThisType operator++(int) { \
114 ThisType temp(*this); \
118 ThisType& operator--() { \
122 const ThisType operator--(int) { \
123 ThisType temp(*this); \
136template <
typename StrongIndexName>
143 return StrongIndexName::TypeName();
148 return static_cast<size_t>(x.value());
164 constexpr int value()
const {
return value_; }
166 template <
typename ValType>
168 return static_cast<ValType
>(value_);
191template <
typename StrongIntegerName>
198 return StrongIntegerName::TypeName();
203 return static_cast<size_t>(x.value());
218 constexpr int64_t
value()
const {
return value_; }
221 template <
typename ValType>
223 return static_cast<ValType
>(value_);
244#undef STRONG_ASSIGNMENT_OP
245#undef INCREMENT_AND_DECREMENT_OPERATORS
250template <
typename StrongIndexName>
253 return os << arg.
value();
256template <
typename Sink,
typename... T>
258 absl::Format(&sink,
"%v", arg.
value());
261template <
typename StrongIntegerName>
264 return os << arg.
value();
267template <
typename Sink,
typename... T>
269 absl::Format(&sink,
"%v", arg.
value());
273#define STRONG_TYPE_ARITHMETIC_OP(StrongType, IntType, op) \
274 template <typename StrongName> \
275 constexpr StrongType<StrongName> operator op(StrongType<StrongName> id_1, \
276 StrongType<StrongName> id_2) { \
277 return StrongType<StrongName>(id_1.value() op id_2.value()); \
279 template <typename StrongName> \
280 constexpr StrongType<StrongName> operator op(StrongType<StrongName> id, \
282 return StrongType<StrongName>(id.value() op arg_val); \
284 template <typename StrongName> \
285 constexpr StrongType<StrongName> operator op(IntType arg_val, \
286 StrongType<StrongName> id) { \
287 return StrongType<StrongName>(arg_val op id.value()); \
302#undef STRONG_TYPE_ARITHMETIC_OP
305#define STRONG_TYPE_COMPARISON_OP(StrongType, IntType, op) \
306 template <typename StrongName> \
307 static inline constexpr bool operator op(StrongType<StrongName> id_1, \
308 StrongType<StrongName> id_2) { \
309 return id_1.value() op id_2.value(); \
311 template <typename StrongName> \
312 static inline constexpr bool operator op(StrongType<StrongName> id, \
314 return id.value() op val; \
316 template <typename StrongName> \
317 static inline constexpr bool operator op(IntType val, \
318 StrongType<StrongName> id) { \
319 return val op id.value(); \
335#undef STRONG_TYPE_COMPARISON_OP
338template <
typename StrongIndexName,
typename H>
340 return H::combine(std::move(h), i.value());
343template <
typename StrongIntegerName,
typename H>
345 return H::combine(std::move(h), i.value());
352template <
typename Tag>
356template <
typename Tag>
364template <
typename Tag>
373 static constexpr bool is_signed = numeric_limits<NativeTypeT>::is_signed;
374 static constexpr bool is_integer = numeric_limits<NativeTypeT>::is_integer;
375 static constexpr bool is_exact = numeric_limits<NativeTypeT>::is_exact;
377 numeric_limits<NativeTypeT>::has_infinity;
379 numeric_limits<NativeTypeT>::has_quiet_NaN;
381 numeric_limits<NativeTypeT>::has_signaling_NaN;
383 numeric_limits<NativeTypeT>::has_denorm;
385 numeric_limits<NativeTypeT>::has_denorm_loss;
387 numeric_limits<NativeTypeT>::round_style;
388 static constexpr bool is_iec559 = numeric_limits<NativeTypeT>::is_iec559;
389 static constexpr bool is_bounded = numeric_limits<NativeTypeT>::is_bounded;
390 static constexpr bool is_modulo = numeric_limits<NativeTypeT>::is_modulo;
391 static constexpr int digits = numeric_limits<NativeTypeT>::digits;
392 static constexpr int digits10 = numeric_limits<NativeTypeT>::digits10;
393 static constexpr int max_digits10 = numeric_limits<NativeTypeT>::max_digits10;
394 static constexpr int radix = numeric_limits<NativeTypeT>::radix;
395 static constexpr int min_exponent = numeric_limits<NativeTypeT>::min_exponent;
397 numeric_limits<NativeTypeT>::min_exponent10;
398 static constexpr int max_exponent = numeric_limits<NativeTypeT>::max_exponent;
400 numeric_limits<NativeTypeT>::max_exponent10;
401 static constexpr bool traps = numeric_limits<NativeTypeT>::traps;
403 numeric_limits<NativeTypeT>::tinyness_before;
406 static constexpr StrongIntT(
min)() {
407 return StrongIntT(numeric_limits<NativeTypeT>::min());
410 return StrongIntT(numeric_limits<NativeTypeT>::lowest());
412 static constexpr StrongIntT(
max)() {
413 return StrongIntT(numeric_limits<NativeTypeT>::max());
415 static constexpr StrongIntT
epsilon() {
return StrongIntT(); }
416 static constexpr StrongIntT
round_error() {
return StrongIntT(); }
417 static constexpr StrongIntT
infinity() {
return StrongIntT(); }
418 static constexpr StrongIntT
quiet_NaN() {
return StrongIntT(); }
420 static constexpr StrongIntT
denorm_min() {
return StrongIntT(); }
423template <
typename Tag>
432 static constexpr bool is_signed = numeric_limits<NativeTypeT>::is_signed;
433 static constexpr bool is_integer = numeric_limits<NativeTypeT>::is_integer;
434 static constexpr bool is_exact = numeric_limits<NativeTypeT>::is_exact;
436 numeric_limits<NativeTypeT>::has_infinity;
438 numeric_limits<NativeTypeT>::has_quiet_NaN;
440 numeric_limits<NativeTypeT>::has_signaling_NaN;
442 numeric_limits<NativeTypeT>::has_denorm;
444 numeric_limits<NativeTypeT>::has_denorm_loss;
446 numeric_limits<NativeTypeT>::round_style;
447 static constexpr bool is_iec559 = numeric_limits<NativeTypeT>::is_iec559;
448 static constexpr bool is_bounded = numeric_limits<NativeTypeT>::is_bounded;
449 static constexpr bool is_modulo = numeric_limits<NativeTypeT>::is_modulo;
450 static constexpr int digits = numeric_limits<NativeTypeT>::digits;
451 static constexpr int digits10 = numeric_limits<NativeTypeT>::digits10;
452 static constexpr int max_digits10 = numeric_limits<NativeTypeT>::max_digits10;
453 static constexpr int radix = numeric_limits<NativeTypeT>::radix;
454 static constexpr int min_exponent = numeric_limits<NativeTypeT>::min_exponent;
456 numeric_limits<NativeTypeT>::min_exponent10;
457 static constexpr int max_exponent = numeric_limits<NativeTypeT>::max_exponent;
459 numeric_limits<NativeTypeT>::max_exponent10;
460 static constexpr bool traps = numeric_limits<NativeTypeT>::traps;
462 numeric_limits<NativeTypeT>::tinyness_before;
465 static constexpr StrongIntT(
min)() {
466 return StrongIntT(numeric_limits<NativeTypeT>::min());
469 return StrongIntT(numeric_limits<NativeTypeT>::lowest());
471 static constexpr StrongIntT(
max)() {
472 return StrongIntT(numeric_limits<NativeTypeT>::max());
474 static constexpr StrongIntT
epsilon() {
return StrongIntT(); }
475 static constexpr StrongIntT
round_error() {
return StrongIntT(); }
476 static constexpr StrongIntT
infinity() {
return StrongIntT(); }
477 static constexpr StrongIntT
quiet_NaN() {
return StrongIntT(); }
479 static constexpr StrongIntT
denorm_min() {
return StrongIntT(); }
StrongIndex & operator=(int arg_value)
STRONG_ASSIGNMENT_OP(StrongIndex, int,+=)
struct ABSL_DEPRECATED("Use absl::Hash instead") Hasher
constexpr ThisType operator-() const
StrongIndex< StrongIndexName > ThisType
INCREMENT_AND_DECREMENT_OPERATORS
constexpr ThisType operator+() const
constexpr StrongIndex(int value)
constexpr int value() const
constexpr ValType value() const
STRONG_ASSIGNMENT_OP(StrongIndex, int, -=)
static constexpr absl::string_view TypeName()
constexpr int64_t value() const
StrongInt64< StrongIntegerName > ThisType
constexpr ValType value() const
constexpr StrongInt64(int64_t value)
NOLINTBEGIN(google-explicit-constructor)
constexpr ThisType operator-() const
STRONG_ASSIGNMENT_OP(StrongInt64, int64_t, *=)
static constexpr absl::string_view TypeName()
constexpr ThisType operator~() const
STRONG_ASSIGNMENT_OP(StrongInt64, int64_t,+=)
STRONG_ASSIGNMENT_OP(StrongInt64, int64_t,<<=)
INCREMENT_AND_DECREMENT_OPERATORS
STRONG_ASSIGNMENT_OP(StrongInt64, int64_t, -=)
STRONG_ASSIGNMENT_OP(StrongInt64, int64_t, %=)
struct ABSL_DEPRECATED("Use absl::Hash instead") Hasher
constexpr ThisType operator+() const
StrongInt64 & operator=(int64_t arg_value)
NOLINTEND(google-explicit-constructor)
int64_t * mutable_value()
STRONG_ASSIGNMENT_OP(StrongInt64, int64_t, > >=)
STRONG_ASSIGNMENT_OP(StrongInt64, int64_t,/=)
In SWIG mode, we don't want anything besides these top-level includes.
H AbslHashValue(H h, const StrongIndex< StrongIndexName > &i)
– ABSL HASHING SUPPORT --------------------------------------------------—
std::ostream & operator<<(std::ostream &out, const Assignment &assignment)
void AbslStringify(Sink &sink, StrongIndex< T... > arg)
#define STRONG_TYPE_COMPARISON_OP(StrongType, IntType, op)
– NON-MEMBER COMPARISON OPERATORS ---------------------------------------—
#define STRONG_TYPE_ARITHMETIC_OP(StrongType, IntType, op)
– NON-MEMBER ARITHMETIC OPERATORS ---------------------------------------—
static constexpr StrongIntT denorm_min()
static constexpr StrongIntT epsilon()
static constexpr bool has_denorm_loss
static constexpr StrongIntT signaling_NaN()
static constexpr StrongIntT round_error()
static constexpr StrongIntT max()
static constexpr int min_exponent10
static constexpr StrongIntT min()
NOLINTEND(google3-readability-class-member-naming)
static constexpr bool has_signaling_NaN
static constexpr int digits10
static constexpr float_round_style round_style
static constexpr float_denorm_style has_denorm
static constexpr int max_exponent
static constexpr bool is_integer
static constexpr int radix
static constexpr int max_digits10
static constexpr int min_exponent
static constexpr StrongIntT infinity()
static constexpr bool has_infinity
static constexpr bool is_specialized
NOLINTBEGIN(google3-readability-class-member-naming)
static constexpr int digits
static constexpr int max_exponent10
static constexpr bool is_signed
static constexpr bool has_quiet_NaN
static constexpr bool tinyness_before
static constexpr bool is_exact
static constexpr bool traps
static constexpr StrongIntT quiet_NaN()
static constexpr StrongIntT lowest()
static constexpr bool is_iec559
static constexpr bool is_bounded
static constexpr bool is_modulo
static constexpr int max_exponent10
static constexpr int max_exponent
static constexpr StrongIntT max()
static constexpr int digits10
static constexpr StrongIntT epsilon()
static constexpr StrongIntT denorm_min()
static constexpr bool is_exact
static constexpr StrongIntT lowest()
static constexpr int min_exponent
static constexpr bool has_quiet_NaN
static constexpr bool has_infinity
static constexpr bool is_bounded
static constexpr StrongIntT infinity()
static constexpr bool is_modulo
static constexpr bool is_specialized
NOLINTBEGIN(google3-readability-class-member-naming)
static constexpr StrongIntT signaling_NaN()
static constexpr bool has_denorm_loss
static constexpr int max_digits10
static constexpr bool has_signaling_NaN
static constexpr int radix
static constexpr StrongIntT round_error()
static constexpr int digits
static constexpr bool traps
static constexpr float_round_style round_style
static constexpr bool is_integer
static constexpr StrongIntT min()
NOLINTEND(google3-readability-class-member-naming)
static constexpr bool tinyness_before
static constexpr StrongIntT quiet_NaN()
static constexpr float_denorm_style has_denorm
static constexpr bool is_iec559
static constexpr int min_exponent10
static constexpr bool is_signed