diff --git a/ortools/flatzinc/cp_model_fz_solver.cc b/ortools/flatzinc/cp_model_fz_solver.cc index 49f4127d086..4735f35dfcc 100644 --- a/ortools/flatzinc/cp_model_fz_solver.cc +++ b/ortools/flatzinc/cp_model_fz_solver.cc @@ -25,6 +25,7 @@ #include "absl/container/flat_hash_set.h" #include "absl/strings/match.h" #include "absl/strings/str_cat.h" +#include "absl/types/span.h" #include "google/protobuf/text_format.h" #include "ortools/base/iterator_adaptors.h" #include "ortools/flatzinc/checker.h" @@ -73,8 +74,8 @@ struct CpModelProtoWithMapping { // Create and return the indices of the IntervalConstraint corresponding // to the flatzinc "interval" specified by a start var and a size var. // This method will cache intervals with the key . - std::vector CreateIntervals(const std::vector& starts, - const std::vector& sizes); + std::vector CreateIntervals(absl::Span starts, + absl::Span sizes); // Create and return the indices of the IntervalConstraint corresponding // to the flatzinc "interval" specified by a start var and a size var. @@ -84,7 +85,7 @@ struct CpModelProtoWithMapping { // stating that the interval will be performed if and only if the size is // greater than 0. std::vector CreateNonZeroOrOptionalIntervals( - const std::vector& starts, const std::vector& sizes); + absl::Span starts, absl::Span sizes); // Create and return the index of the optional IntervalConstraint // corresponding to the flatzinc "interval" specified by a start var, the @@ -104,7 +105,7 @@ struct CpModelProtoWithMapping { // Helpers to fill a ConstraintProto. void FillAMinusBInDomain(const std::vector& domain, const fz::Constraint& fz_ct, ConstraintProto* ct); - void FillLinearConstraintWithGivenDomain(const std::vector& domain, + void FillLinearConstraintWithGivenDomain(absl::Span domain, const fz::Constraint& fz_ct, ConstraintProto* ct); void FillConstraint(const fz::Constraint& fz_ct, ConstraintProto* ct); @@ -114,7 +115,7 @@ struct CpModelProtoWithMapping { // Translates the flatzinc search annotations into the CpModelProto // search_order field. void TranslateSearchAnnotations( - const std::vector& search_annotations, + absl::Span search_annotations, SolverLogger* logger); // The output proto. @@ -293,7 +294,7 @@ int CpModelProtoWithMapping::GetOrCreateOptionalInterval(int start_var, } std::vector CpModelProtoWithMapping::CreateIntervals( - const std::vector& starts, const std::vector& sizes) { + absl::Span starts, absl::Span sizes) { std::vector intervals; for (int i = 0; i < starts.size(); ++i) { intervals.push_back( @@ -303,7 +304,7 @@ std::vector CpModelProtoWithMapping::CreateIntervals( } std::vector CpModelProtoWithMapping::CreateNonZeroOrOptionalIntervals( - const std::vector& starts, const std::vector& sizes) { + absl::Span starts, absl::Span sizes) { std::vector intervals; for (int i = 0; i < starts.size(); ++i) { const int opt_var = NonZeroLiteralFrom(sizes[i]); @@ -394,7 +395,7 @@ void CpModelProtoWithMapping::FillAMinusBInDomain( } void CpModelProtoWithMapping::FillLinearConstraintWithGivenDomain( - const std::vector& domain, const fz::Constraint& fz_ct, + absl::Span domain, const fz::Constraint& fz_ct, ConstraintProto* ct) { auto* arg = ct->mutable_linear(); for (const int64_t domain_bound : domain) arg->add_domain(domain_bound); @@ -1097,8 +1098,7 @@ void CpModelProtoWithMapping::FillReifOrImpliedConstraint( } void CpModelProtoWithMapping::TranslateSearchAnnotations( - const std::vector& search_annotations, - SolverLogger* logger) { + absl::Span search_annotations, SolverLogger* logger) { std::vector flat_annotations; for (const fz::Annotation& annotation : search_annotations) { fz::FlattenAnnotations(annotation, &flat_annotations); diff --git a/ortools/flatzinc/model.cc b/ortools/flatzinc/model.cc index e46cdfee163..a9050961749 100644 --- a/ortools/flatzinc/model.cc +++ b/ortools/flatzinc/model.cc @@ -26,6 +26,7 @@ #include "absl/strings/str_format.h" #include "absl/strings/str_join.h" #include "absl/strings/string_view.h" +#include "absl/types/span.h" #include "ortools/base/stl_util.h" #include "ortools/util/logging.h" @@ -200,7 +201,7 @@ bool Domain::IntersectWithInterval(int64_t interval_min, int64_t interval_max) { return false; } -bool Domain::IntersectWithListOfIntegers(const std::vector& integers) { +bool Domain::IntersectWithListOfIntegers(absl::Span integers) { if (is_interval) { const int64_t dmin = values.empty() ? std::numeric_limits::min() : values[0]; @@ -370,7 +371,7 @@ bool Domain::Contains(int64_t value) const { namespace { bool IntervalOverlapValues(int64_t lb, int64_t ub, - const std::vector& values) { + absl::Span values) { for (int64_t value : values) { if (lb <= value && value <= ub) { return true; diff --git a/ortools/flatzinc/model.h b/ortools/flatzinc/model.h index 55bcee1fe5e..b0f4827c0e9 100644 --- a/ortools/flatzinc/model.h +++ b/ortools/flatzinc/model.h @@ -22,6 +22,7 @@ #include "absl/container/flat_hash_map.h" #include "absl/strings/string_view.h" +#include "absl/types/span.h" #include "ortools/base/logging.h" #include "ortools/base/types.h" #include "ortools/graph/iterators.h" @@ -94,7 +95,7 @@ struct Domain { bool IntersectWithSingleton(int64_t value); bool IntersectWithDomain(const Domain& domain); bool IntersectWithInterval(int64_t interval_min, int64_t interval_max); - bool IntersectWithListOfIntegers(const std::vector& integers); + bool IntersectWithListOfIntegers(absl::Span integers); bool IntersectWithFloatDomain(const Domain& domain); // Returns true iff the value did belong to the domain, and was removed. diff --git a/ortools/graph/util.cc b/ortools/graph/util.cc index a5d7ac37fc1..ea13ba636e5 100644 --- a/ortools/graph/util.cc +++ b/ortools/graph/util.cc @@ -15,9 +15,11 @@ #include +#include "absl/types/span.h" + namespace util { -bool IsSubsetOf0N(const std::vector& v, int n) { +bool IsSubsetOf0N(absl::Span v, int n) { std::vector mask(n, false); for (const int i : v) { if (i < 0 || i >= n || mask[i]) return false; diff --git a/ortools/graph/util.h b/ortools/graph/util.h index bd8b9917f5f..3aa56dc9f07 100644 --- a/ortools/graph/util.h +++ b/ortools/graph/util.h @@ -28,6 +28,7 @@ #include "absl/container/btree_map.h" #include "absl/container/flat_hash_map.h" #include "absl/container/inlined_vector.h" +#include "absl/types/span.h" #include "ortools/base/hash.h" #include "ortools/base/map_util.h" #include "ortools/graph/connected_components.h" @@ -85,7 +86,7 @@ std::unique_ptr RemapGraph(const Graph& graph, // be done in O(num new nodes + num new arcs) but with a higher constant. template std::unique_ptr GetSubgraphOfNodes(const Graph& graph, - const std::vector& nodes); + absl::Span nodes); // This can be used to view a directed graph (that supports reverse arcs) // from graph.h as un undirected graph: operator[](node) returns a @@ -141,7 +142,7 @@ std::vector GetWeaklyConnectedComponents(const Graph& graph) { // Returns true iff the given vector is a subset of [0..n-1], i.e. // all elements i are such that 0 <= i < n and no two elements are equal. // "n" must be >= 0 or the result is undefined. -bool IsSubsetOf0N(const std::vector& v, int n); +bool IsSubsetOf0N(absl::Span v, int n); // Returns true iff the given vector is a permutation of [0..size()-1]. inline bool IsValidPermutation(const std::vector& v) { @@ -295,7 +296,7 @@ std::unique_ptr RemapGraph(const Graph& old_graph, template std::unique_ptr GetSubgraphOfNodes(const Graph& old_graph, - const std::vector& nodes) { + absl::Span nodes) { typedef typename Graph::NodeIndex NodeIndex; typedef typename Graph::ArcIndex ArcIndex; DCHECK(IsSubsetOf0N(nodes, old_graph.num_nodes())) << "Invalid subset"; diff --git a/ortools/linear_solver/linear_solver.h b/ortools/linear_solver/linear_solver.h index c7e3eac8ef0..ba1b543bccf 100644 --- a/ortools/linear_solver/linear_solver.h +++ b/ortools/linear_solver/linear_solver.h @@ -138,6 +138,7 @@ #include #include #include +#include #include #include #include diff --git a/ortools/util/strong_integers.h b/ortools/util/strong_integers.h index 13139bf4267..1f7d8c52019 100644 --- a/ortools/util/strong_integers.h +++ b/ortools/util/strong_integers.h @@ -54,6 +54,7 @@ #include #include +#include #include // NOLINT #include "absl/strings/str_format.h" @@ -346,12 +347,135 @@ H AbslHashValue(H h, const StrongInt64& i) { // -- STD HASHING SUPPORT ----------------------------------------------------- namespace std { template -struct hash > +struct hash> : ::operations_research::StrongIndex::Hasher {}; template -struct hash > +struct hash> : ::operations_research::StrongInt64::Hasher {}; } // namespace std +// -- STD NUMERIC_LIMITS SUPPORT ---------------------------------------------- +namespace std { + +template +struct numeric_limits> { + private: + using StrongIntT = operations_research::StrongIndex; + using NativeTypeT = typename operations_research::StrongIndex::ValueType; + + public: + // NOLINTBEGIN(google3-readability-class-member-naming) + static constexpr bool is_specialized = true; + static constexpr bool is_signed = numeric_limits::is_signed; + static constexpr bool is_integer = numeric_limits::is_integer; + static constexpr bool is_exact = numeric_limits::is_exact; + static constexpr bool has_infinity = + numeric_limits::has_infinity; + static constexpr bool has_quiet_NaN = + numeric_limits::has_quiet_NaN; + static constexpr bool has_signaling_NaN = + numeric_limits::has_signaling_NaN; + static constexpr float_denorm_style has_denorm = + numeric_limits::has_denorm; + static constexpr bool has_denorm_loss = + numeric_limits::has_denorm_loss; + static constexpr float_round_style round_style = + numeric_limits::round_style; + static constexpr bool is_iec559 = numeric_limits::is_iec559; + static constexpr bool is_bounded = numeric_limits::is_bounded; + static constexpr bool is_modulo = numeric_limits::is_modulo; + static constexpr int digits = numeric_limits::digits; + static constexpr int digits10 = numeric_limits::digits10; + static constexpr int max_digits10 = numeric_limits::max_digits10; + static constexpr int radix = numeric_limits::radix; + static constexpr int min_exponent = numeric_limits::min_exponent; + static constexpr int min_exponent10 = + numeric_limits::min_exponent10; + static constexpr int max_exponent = numeric_limits::max_exponent; + static constexpr int max_exponent10 = + numeric_limits::max_exponent10; + static constexpr bool traps = numeric_limits::traps; + static constexpr bool tinyness_before = + numeric_limits::tinyness_before; + // NOLINTEND(google3-readability-class-member-naming) + + static constexpr StrongIntT(min)() { + return StrongIntT(numeric_limits::min()); + } + static constexpr StrongIntT lowest() { + return StrongIntT(numeric_limits::lowest()); + } + static constexpr StrongIntT(max)() { + return StrongIntT(numeric_limits::max()); + } + static constexpr StrongIntT epsilon() { return StrongIntT(); } + static constexpr StrongIntT round_error() { return StrongIntT(); } + static constexpr StrongIntT infinity() { return StrongIntT(); } + static constexpr StrongIntT quiet_NaN() { return StrongIntT(); } + static constexpr StrongIntT signaling_NaN() { return StrongIntT(); } + static constexpr StrongIntT denorm_min() { return StrongIntT(); } +}; + +template +struct numeric_limits> { + private: + using StrongIntT = operations_research::StrongInt64; + using NativeTypeT = typename operations_research::StrongInt64::ValueType; + + public: + // NOLINTBEGIN(google3-readability-class-member-naming) + static constexpr bool is_specialized = true; + static constexpr bool is_signed = numeric_limits::is_signed; + static constexpr bool is_integer = numeric_limits::is_integer; + static constexpr bool is_exact = numeric_limits::is_exact; + static constexpr bool has_infinity = + numeric_limits::has_infinity; + static constexpr bool has_quiet_NaN = + numeric_limits::has_quiet_NaN; + static constexpr bool has_signaling_NaN = + numeric_limits::has_signaling_NaN; + static constexpr float_denorm_style has_denorm = + numeric_limits::has_denorm; + static constexpr bool has_denorm_loss = + numeric_limits::has_denorm_loss; + static constexpr float_round_style round_style = + numeric_limits::round_style; + static constexpr bool is_iec559 = numeric_limits::is_iec559; + static constexpr bool is_bounded = numeric_limits::is_bounded; + static constexpr bool is_modulo = numeric_limits::is_modulo; + static constexpr int digits = numeric_limits::digits; + static constexpr int digits10 = numeric_limits::digits10; + static constexpr int max_digits10 = numeric_limits::max_digits10; + static constexpr int radix = numeric_limits::radix; + static constexpr int min_exponent = numeric_limits::min_exponent; + static constexpr int min_exponent10 = + numeric_limits::min_exponent10; + static constexpr int max_exponent = numeric_limits::max_exponent; + static constexpr int max_exponent10 = + numeric_limits::max_exponent10; + static constexpr bool traps = numeric_limits::traps; + static constexpr bool tinyness_before = + numeric_limits::tinyness_before; + // NOLINTEND(google3-readability-class-member-naming) + + static constexpr StrongIntT(min)() { + return StrongIntT(numeric_limits::min()); + } + static constexpr StrongIntT lowest() { + return StrongIntT(numeric_limits::lowest()); + } + static constexpr StrongIntT(max)() { + return StrongIntT(numeric_limits::max()); + } + static constexpr StrongIntT epsilon() { return StrongIntT(); } + static constexpr StrongIntT round_error() { return StrongIntT(); } + static constexpr StrongIntT infinity() { return StrongIntT(); } + static constexpr StrongIntT quiet_NaN() { return StrongIntT(); } + static constexpr StrongIntT signaling_NaN() { return StrongIntT(); } + static constexpr StrongIntT denorm_min() { return StrongIntT(); } +}; + +} // namespace std + #endif // OR_TOOLS_UTIL_STRONG_INTEGERS_H_