145#ifndef OR_TOOLS_BASE_STRONG_INT_H_
146#define OR_TOOLS_BASE_STRONG_INT_H_
153#include <type_traits>
155#include "absl/base/port.h"
156#include "absl/strings/str_format.h"
157#include "absl/strings/string_view.h"
162template <
typename StrongIntName,
typename _ValueType>
168#define DEFINE_STRONG_INT_TYPE(int_type_name, value_type) \
169 struct int_type_name##_tag_ { \
170 static constexpr absl::string_view TypeName() { return #int_type_name; } \
172 typedef ::util_intops::StrongInt<int_type_name##_tag_, value_type> \
185template <
typename StrongIntName,
typename _ValueType>
192 return StrongIntName::TypeName();
199 return static_cast<size_t>(arg.
value());
219 template <
typename ValType>
221 return static_cast<ValType
>(value_);
226 template <
typename T,
227 typename = std::enable_if_t<std::conjunction_v<
228 std::bool_constant<std::numeric_limits<T>::is_integer>,
229 std::is_convertible<ValueType, T>>>>
230 constexpr explicit operator T()
const {
231 return static_cast<T
>(value_);
254 constexpr bool operator!()
const {
return value_ == 0; }
262#define STRONG_INT_TYPE_ASSIGNMENT_OP(op) \
263 ThisType& operator op(const ThisType & arg_value) { \
264 value_ op arg_value.value(); \
267 ThisType& operator op(ValueType arg_value) { \
268 value_ op arg_value; \
278#undef STRONG_INT_TYPE_ASSIGNMENT_OP
290 invalid_integer_type_for_id_type_);
296template <
typename StrongIntName,
typename ValueType>
299 return os << arg.
value();
305template <
typename Sink,
typename... T>
307 using ValueType =
typename decltype(arg)::ValueType;
310 if constexpr (std::is_same_v<ValueType, int8_t>) {
311 absl::Format(&sink,
"%d", arg.
value());
312 }
else if constexpr (std::is_same_v<ValueType, uint8_t>) {
313 absl::Format(&sink,
"%u", arg.
value());
315 absl::Format(&sink,
"%v", arg.
value());
327#define STRONG_INT_TYPE_ARITHMETIC_OP(op) \
328 template <typename StrongIntName, typename ValueType> \
329 constexpr StrongInt<StrongIntName, ValueType> operator op( \
330 StrongInt<StrongIntName, ValueType> id_1, \
331 StrongInt<StrongIntName, ValueType> id_2) { \
332 return StrongInt<StrongIntName, ValueType>(id_1.value() op id_2.value()); \
334 template <typename StrongIntName, typename ValueType> \
335 constexpr StrongInt<StrongIntName, ValueType> operator op( \
336 StrongInt<StrongIntName, ValueType> id, \
337 typename StrongInt<StrongIntName, ValueType>::ValueType arg_val) { \
338 return StrongInt<StrongIntName, ValueType>(id.value() op arg_val); \
340 template <typename StrongIntName, typename ValueType> \
341 constexpr StrongInt<StrongIntName, ValueType> operator op( \
342 typename StrongInt<StrongIntName, ValueType>::ValueType arg_val, \
343 StrongInt<StrongIntName, ValueType> id) { \
344 return StrongInt<StrongIntName, ValueType>(arg_val op id.value()); \
353#undef STRONG_INT_TYPE_ARITHMETIC_OP
361#define STRONG_INT_TYPE_COMPARISON_OP(op) \
362 template <typename StrongIntName, typename ValueType> \
363 static inline constexpr bool operator op( \
364 StrongInt<StrongIntName, ValueType> id_1, \
365 StrongInt<StrongIntName, ValueType> id_2) { \
366 return id_1.value() op id_2.value(); \
368 template <typename StrongIntName, typename ValueType> \
369 static inline constexpr bool operator op( \
370 StrongInt<StrongIntName, ValueType> id, \
371 typename StrongInt<StrongIntName, ValueType>::ValueType val) { \
372 return id.value() op val; \
374 template <typename StrongIntName, typename ValueType> \
375 static inline constexpr bool operator op( \
376 typename StrongInt<StrongIntName, ValueType>::ValueType val, \
377 StrongInt<StrongIntName, ValueType> id) { \
378 return val op id.value(); \
386#undef STRONG_INT_TYPE_COMPARISON_OP
390template <
typename IntType>
404 return current_ != other.current_;
407 return current_ == other.current_;
433 const StrongIntRangeIterator begin_;
434 const StrongIntRangeIterator end_;
437template <
typename IntType>
442template <
typename IntType>
450template <
typename StrongIntName,
typename ValueType>
Iterator over the indices.
StrongIntRangeIterator(IntType initial)
bool operator!=(const StrongIntRangeIterator &other) const
bool operator==(const StrongIntRangeIterator &other) const
StrongIntRangeIterator operator++(int)
pointer operator->() const
value_type operator*() const
const IntType & reference
std::input_iterator_tag iterator_category
StrongIntRangeIterator & operator++()
StrongIntRange(IntType end)
Loops from IntType(0) up to (but not including) end.
StrongIntRange(IntType begin, IntType end)
Loops from begin up to (but not including) end.
StrongIntRangeIterator end() const
StrongIntRangeIterator begin() const
constexpr ValueType value() const
constexpr ValType value() const
ThisType & operator=(ValueType arg_value)
STRONG_INT_TYPE_ASSIGNMENT_OP(> >=)
constexpr StrongInt(ValueType value)
C'tor explicitly initializing from a ValueType.
STRONG_INT_TYPE_ASSIGNMENT_OP(%=)
constexpr bool operator!() const
StrongInt< StrongIntName, ValueType > ThisType
const ThisType operator++(int v)
constexpr const ThisType operator~() const
ThisType & operator++()
– UNARY OPERATORS -----------------------------------------------------—
constexpr const ThisType operator-() const
static constexpr absl::string_view TypeName()
const ThisType operator--(int v)
STRONG_INT_TYPE_ASSIGNMENT_OP(-=)
constexpr const ThisType operator+() const
STRONG_INT_TYPE_ASSIGNMENT_OP * STRONG_INT_TYPE_ASSIGNMENT_OP(/=);STRONG_INT_TYPE_ASSIGNMENT_OP(<<=
STRONG_INT_TYPE_ASSIGNMENT_OP(+=)
constexpr StrongInt()
Default c'tor initializing value_ to 0.
#define COMPILE_ASSERT(x, msg)
STRONG_INT_TYPE_COMPARISON_OP(==)
StrongIntRange< IntType > MakeStrongIntRange(IntType end)
void AbslStringify(Sink &sink, StrongInt< T... > arg)
std::ostream & operator<<(std::ostream &os, StrongInt< StrongIntName, ValueType > arg)
class util_intops::StrongInt ABSL_ATTRIBUTE_PACKED
std::optional< int64_t > end
#define STRONG_INT_TYPE_ASSIGNMENT_OP(op)
#define STRONG_INT_TYPE_ARITHMETIC_OP(op)
size_t operator()(const StrongInt &arg) const