backport from main branch

* bazel: add missing python typing-extensions requirements
* use [[maybe_unused]] standard attribute
* linear_solver: improve LpQuadraticTerm support
This commit is contained in:
Corentin Le Molgat
2025-04-30 15:10:49 +02:00
parent be4fd34372
commit 3067056625
17 changed files with 389 additions and 430 deletions

View File

@@ -3,8 +3,9 @@ absl-py==2.1.0
immutabledict==3.0.0
numpy==2.2.0
protobuf==6.30.2
requests==2.32.0
requests==2.32.3
scipy==1.14.1
typing-extensions==4.13.1
# OR-Tools build dependencies
mypy==1.6.1
@@ -20,10 +21,10 @@ svgwrite==1.4.3
plotly==5.15.0
# Notebook
jupyterlab==4.2.5
notebook==7.2.2
jupyter-server==2.14.2
jupyterlab==4.4.1
notebook==7.4.1
jupyter-server==2.15.0
tornado==6.4.2
Pygments==2.15.0
jsonschema==4.19.0
jinja2==3.1.5
jinja2==3.1.6

View File

@@ -85,7 +85,7 @@ isoduration==20.11.0
# via jsonschema
jedi==0.19.0
# via ipython
jinja2==3.1.5
jinja2==3.1.6
# via
# -r bazel/notebook_requirements.in
# jupyter-server
@@ -118,11 +118,11 @@ jupyter-core==5.3.1
# nbclient
# nbconvert
# nbformat
jupyter-events==0.9.0
jupyter-events==0.12.0
# via jupyter-server
jupyter-lsp==2.2.2
# via jupyterlab
jupyter-server==2.14.2
jupyter-server==2.15.0
# via
# -r bazel/notebook_requirements.in
# jupyter-lsp
@@ -132,7 +132,7 @@ jupyter-server==2.14.2
# notebook-shim
jupyter-server-terminals==0.4.4
# via jupyter-server
jupyterlab==4.2.5
jupyterlab==4.4.1
# via
# -r bazel/notebook_requirements.in
# notebook
@@ -171,7 +171,7 @@ nbformat==5.9.2
# nbconvert
nest-asyncio==1.5.7
# via ipykernel
notebook==7.2.2
notebook==7.4.1
# via -r bazel/notebook_requirements.in
notebook-shim==0.2.3
# via
@@ -188,6 +188,7 @@ packaging==23.1
# via
# black
# ipykernel
# jupyter-events
# jupyter-server
# jupyterlab
# jupyterlab-server
@@ -256,7 +257,7 @@ referencing==0.30.2
# jsonschema
# jsonschema-specifications
# jupyter-events
requests==2.32.0
requests==2.32.3
# via
# -r bazel/notebook_requirements.in
# jupyterlab-server
@@ -325,8 +326,10 @@ traitlets==5.9.0
# nbformat
types-protobuf==4.24.0.0
# via mypy-protobuf
typing-extensions==4.8.0
# via mypy
typing-extensions==4.13.1
# via
# -r bazel/notebook_requirements.in
# mypy
tzdata==2023.3
# via pandas
uri-template==1.3.0

View File

@@ -5,6 +5,7 @@ numpy==2.2.0
protobuf==6.30.2
requests==2.32.3
scipy==1.14.1
typing-extensions==4.13.1
# OR-Tools build dependencies
mypy==1.6.1

View File

@@ -63,8 +63,10 @@ svgwrite==1.4.3
# via -r bazel/ortools_requirements.in
types-protobuf==4.24.0.0
# via mypy-protobuf
typing-extensions==4.8.0
# via mypy
typing-extensions==4.13.1
# via
# -r bazel/ortools_requirements.in
# mypy
tzdata==2023.3
# via pandas
urllib3==2.2.2

View File

@@ -14,6 +14,7 @@
"""Build definitions for SWIG Java."""
load("@bazel_skylib//lib:paths.bzl", "paths")
load("@rules_cc//cc:defs.bzl", "cc_library")
load("@rules_java//java:java_library.bzl", "java_library")
load("@rules_java//java/common:java_common.bzl", "java_common")
@@ -195,8 +196,7 @@ def ortools_java_wrap_cc(
visibility = ["//visibility:private"],
**kwargs
)
native.cc_library(
cc_library(
name = cc_name,
srcs = [outfile],
hdrs = [outhdr] if use_directors else [],

View File

@@ -183,85 +183,86 @@ Following is a list of available options, for the full list run:
cmake -S. -Bbuild -LH
```
| CMake Option | Default Value | Note |
|:-------------|:--------------|:-----|
| `CMAKE_BUILD_TYPE` | Release | see CMake documentation [here](https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html) |
| `BUILD_CXX` | ON | Build C++ |
| `BUILD_DOTNET` | OFF | Build .Net wrapper and packages |
| `BUILD_JAVA` | OFF | Build Java wrapper and packages |
| `BUILD_PYTHON` | OFF | Build Python wrapper and package |
| | | |
| `BUILD_FLATZINC` | ON\* | Build the flatzinc library<br>**Forced** to OFF if `BUILD_CXX=OFF` |
| `BUILD_GLOP` | OFF\* | Build the standalone Glop library<br>**Forced** to OFF if `BUILD_CXX=ON`, otherwise default to ON |
| | | |
| `BUILD_DEPS` | OFF* | Default to ON if `BUILD_JAVA=ON` or `BUILD_PYTHON=ON` or `BUILD_DOTNET=ON` |
| `BUILD_ZLIB` | OFF* | Build the zlib dynamic library<br>**Forced** to ON if `BUILD_DEPS=ON` |
| `BUILD_absl` | OFF* | Build the abseil-cpp dynamic libraries<br>**Forced** to ON if `BUILD_DEPS=ON` |
| `BUILD_Protobuf` | OFF* | Build the protobuf dynamic libraries<br>**Forced** to ON if `BUILD_DEPS=ON` |
| `BUILD_re2` | OFF* | Build the re2 dynamic libraries<br>**Forced** to ON if `BUILD_DEPS=ON` |
| `BUILD_Eigen3` | OFF* | Build the Eigen3 libraries<br>**Forced** to ON if `BUILD_DEPS=ON` |
| | | |
| `USE_COINOR` | ON\* | Enable Coin-OR support<br>**Forced** to OFF if `BUILD_CXX=OFF` |
| `BUILD_CoinUtils` | OFF\* | Build the CoinUtils dynamic library<br>**Forced** to ON if `USE_COINOR=ON` **and** `BUILD_DEPS=ON` |
| `BUILD_Osi` | OFF\* | Build the Osi dynamic library<br>**Forced** to ON if `USE_COINOR=ON` **and** `BUILD_DEPS=ON` |
| `BUILD_Clp` | OFF\* | Build the Clp dynamic library<br>**Forced** to ON if `USE_COINOR=ON` **and** `BUILD_DEPS=ON` |
| `BUILD_Cgl` | OFF\* | Build the Cgl dynamic library<br>**Forced** to ON if `USE_COINOR=ON` **and** `BUILD_DEPS=ON` |
| `BUILD_Cbc` | OFF\* | Build the Cbc dynamic library<br>**Forced** to ON if `USE_COINOR=ON` **and** `BUILD_DEPS=ON` |
| | | |
| `USE_GLPK` | OFF\* | Enable GLPK support<br>**Forced** to OFF if `BUILD_CXX=OFF` |
| `BUILD_GLPK` | OFF\* | Build the GLPK dynamic libraries<br>**Forced** to ON if `USE_GLPK=ON` **and** `BUILD_DEPS=ON` |
| | | |
| `USE_HIGHS` | ON\* | Enable HIGHS support<br>**Forced** to OFF if `BUILD_CXX=OFF` |
| `BUILD_HIGHS` | OFF\* | Build the HiGHS dynamic libraries<br>**Forced** to ON if `USE_HIGHS=ON` **and** `BUILD_DEPS=ON` |
| | | |
| `USE_SCIP` | ON\* | Enable SCIP support<br>**Forced** to OFF if `BUILD_CXX=OFF` |
| `BUILD_SCIP` | OFF\* | Build the SCIP dynamic libraries<br>**Forced** to ON if `USE_SCIP=ON` **and** `BUILD_DEPS=ON` |
| | | |
| `USE_CPLEX` | OFF | Enable CPLEX support |
| | | |
| `BUILD_DOC` | OFF\* | Build all documentations |
| `BUILD_CXX_DOC` | OFF\* | Build C++ documentation<br>**Forced** to ON if `BUILD_DOC=ON` |
| `BUILD_DOTNET_DOC` | OFF\* | Build .Net documentation<br>**Forced** to ON if `BUILD_DOC=ON` |
| `BUILD_JAVA_DOC` | OFF\* | Build Java documentation<br>**Forced** to ON if `BUILD_DOC=ON` |
| `BUILD_PYTHON_DOC` | OFF\* | Build Python documentation<br>**Forced** to ON if `BUILD_DOC=ON` |
| `INSTALL_DOC` | OFF\* | Install all documentations<br>**Forced** to OFF if `BUILD_CXX=OFF` or `BUILD_DOC=OFF` |
| | | |
| `BUILD_SAMPLES` | ON\* | Build all samples<br>Default to ON if `BUILD_DEPS=ON` |
| `BUILD_CXX_SAMPLES` | ON\* | Build all C++ samples<br>**Forced** to OFF if `BUILD_CXX=OFF` or `BUILD_SAMPLE=OFF` |
| `BUILD_DOTNET_SAMPLES` | ON\* | Build all .Net samples<br>**Forced** to OFF if `BUILD_DOTNET=OFF` or `BUILD_SAMPLE=OFF` |
| `BUILD_JAVA_SAMPLES` | ON\* | Build all Java samples<br>**Forced** to OFF if `BUILD_JAVA=OFF` or `BUILD_SAMPLE=OFF` |
| `BUILD_PYTHON_SAMPLES` | ON\* | Build all Python samples<br>**Forced** to OFF if `BUILD_PYTHON=OFF` or `BUILD_SAMPLE=OFF` |
| | | |
| `BUILD_EXAMPLES` | ON\* | Build all examples<br>Default to ON if `BUILD_DEPS=ON` |
| `BUILD_CXX_EXAMPLES` | ON\* | Build all C++ examples<br>**Forced** to OFF if `BUILD_CXX=OFF` or `BUILD_SAMPLE=OFF` |
| `BUILD_DOTNET_EXAMPLES` | ON\* | Build all .Net examples<br>**Forced** to OFF if `BUILD_DOTNET=OFF` or `BUILD_SAMPLE=OFF` |
| `BUILD_JAVA_EXAMPLES` | ON\* | Build all Java examples<br>**Forced** to OFF if `BUILD_JAVA=OFF` or `BUILD_SAMPLE=OFF` |
| `BUILD_PYTHON_EXAMPLES` | ON\* | Build all Python examples<br>**Forced** to OFF if `BUILD_PYTHON=OFF` or `BUILD_SAMPLE=OFF` |
| | | |
| `USE_DOTNET_46` | OFF | Enable .Net Framework 4.6 support<br>Only available if `BUILD_DOTNET=ON` |
| `USE_DOTNET_461` | OFF | Enable .Net Framework 4.6.1 support<br>Only available if `BUILD_DOTNET=ON` |
| `USE_DOTNET_462` | OFF | Enable .Net Framework 4.6.2 support<br>Only available if `BUILD_DOTNET=ON` |
| `USE_DOTNET_48` | OFF | Enable .Net Framework 4.8 support<br>Only available if `BUILD_DOTNET=ON` |
| `USE_DOTNET_STD_21` | OFF | Enable .Net Standard 2.1 support<br>Only available if `BUILD_DOTNET=ON` and not targeting arm64 platform |
| `USE_DOTNET_CORE_31` | OFF | Enable .Net Core 3.1 LTS support<br>Only available if `BUILD_DOTNET=ON` and not targeting arm64 platform |
| `USE_DOTNET_6` | ON | Enable .Net 6 LTS support<br>Only available if `BUILD_DOTNET=ON` |
| `USE_DOTNET_7` | OFF | Enable .Net 7 support<br>Only available if `BUILD_DOTNET=ON` |
| `USE_DOTNET_8` | OFF | Enable .Net 8 LTS support<br>Only available if `BUILD_DOTNET=ON` |
| `USE_DOTNET_9` | OFF | Enable .Net 9 support<br>Only available if `BUILD_DOTNET=ON` |
| `UNIVERSAL_DOTNET_PACKAGE` | OFF | Build a multi platform package (i.e. `Google.OrTools` will depends on all runtime packages)<br>Only available if `BUILD_DOTNET=ON` |
| | | |
| `SKIP_GPG` | ON | Disable GPG sign<br>Only available if `BUILD_JAVA=ON` |
| `UNIVERSAL_JAVA_PACKAGE` | OFF | Build a multi platform package (i.e. `ortools-java` will depends on all native packages)<br>Only available if `BUILD_JAVA=ON` |
| `BUILD_FAT_JAR` | OFF | Build a `ortools-java` .jar that includes all of its own Maven dependencies, including the native package<br>Only available if `BUILD_JAVA=ON` |
| | | |
| `BUILD_pybind11` | `BUILD_DEPS` | Static build the pybind11 libraries<br>**Forced** to ON if `BUILD_DEPS=ON`<br>Only available if `BUILD_PYTHON=ON` |
| `BUILD_pybind11_abseil` | `BUILD_DEPS` | Static build the pybind11_abseil libraries<br>**Forced** to ON if `BUILD_DEPS=ON`<br>Only available if `BUILD_PYTHON=ON` |
| `BUILD_pybind11_protobuf` | `BUILD_DEPS` | Static build the pybind11_protobuf libraries<br>**Forced** to ON if `BUILD_DEPS=ON`<br>Only available if `BUILD_PYTHON=ON` |
| `GENERATE_PYTHON_STUB` | ON | Generate python stub files<br>Only available if `BUILD_PYTHON=ON` |
| `BUILD_VENV` | `BUILD_TESTING` | Create python venv in `BINARY_DIR/python/venv`<br>**Forced** to ON if `BUILD_TESTING=ON`<br>Only available if `BUILD_PYTHON=ON` |
| `VENV_USE_SYSTEM_SITE_PACKAGES` | OFF | Python venv can use system site package (e.g. `py3-numpy` on Alpine)<br>Only available if `BUILD_PYTHON=ON` and `BUILD_VENV=ON` |
| `FETCH_PYTHON_DEPS` | `BUILD_DEPS` | Fetch python modules needed to build ortools package<br>Only available if `BUILD_PYTHON=ON` |
| | | |
CMake Option | Default Value | Note
:------------------------------ | :-------------- | :---
`CMAKE_BUILD_TYPE` | Release | see CMake documentation [here](https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html)
`BUILD_CXX` | ON | Build C++
`BUILD_DOTNET` | OFF | Build .Net wrapper and packages
`BUILD_JAVA` | OFF | Build Java wrapper and packages
`BUILD_PYTHON` | OFF | Build Python wrapper and package
| |
`BUILD_FLATZINC` | ON\* | Build the flatzinc library<br>**Forced** to OFF if `BUILD_CXX=OFF`
`BUILD_GLOP` | OFF\* | Build the standalone Glop library<br>**Forced** to OFF if `BUILD_CXX=ON`, otherwise default to ON
| |
`BUILD_DEPS` | OFF* | Default to ON if `BUILD_JAVA=ON` or `BUILD_PYTHON=ON` or `BUILD_DOTNET=ON`
`BUILD_ZLIB` | OFF* | Build the zlib dynamic library<br>**Forced** to ON if `BUILD_DEPS=ON`
`BUILD_BZip2` | OFF* | Build the bzip2 dynamic library<br>**Forced** to ON if `BUILD_DEPS=ON`
`BUILD_absl` | OFF* | Build the abseil-cpp dynamic libraries<br>**Forced** to ON if `BUILD_DEPS=ON`
`BUILD_Protobuf` | OFF* | Build the protobuf dynamic libraries<br>**Forced** to ON if `BUILD_DEPS=ON`
`BUILD_re2` | OFF* | Build the re2 dynamic libraries<br>**Forced** to ON if `BUILD_DEPS=ON`
`BUILD_Eigen3` | OFF* | Build the Eigen3 libraries<br>**Forced** to ON if `BUILD_DEPS=ON`
| |
`USE_COINOR` | ON\* | Enable Coin-OR support<br>**Forced** to OFF if `BUILD_CXX=OFF`
`BUILD_CoinUtils` | OFF\* | Build the CoinUtils dynamic library<br>**Forced** to ON if `USE_COINOR=ON` **and** `BUILD_DEPS=ON`
`BUILD_Osi` | OFF\* | Build the Osi dynamic library<br>**Forced** to ON if `USE_COINOR=ON` **and** `BUILD_DEPS=ON`
`BUILD_Clp` | OFF\* | Build the Clp dynamic library<br>**Forced** to ON if `USE_COINOR=ON` **and** `BUILD_DEPS=ON`
`BUILD_Cgl` | OFF\* | Build the Cgl dynamic library<br>**Forced** to ON if `USE_COINOR=ON` **and** `BUILD_DEPS=ON`
`BUILD_Cbc` | OFF\* | Build the Cbc dynamic library<br>**Forced** to ON if `USE_COINOR=ON` **and** `BUILD_DEPS=ON`
| |
`USE_GLPK` | OFF\* | Enable GLPK support<br>**Forced** to OFF if `BUILD_CXX=OFF`
`BUILD_GLPK` | OFF\* | Build the GLPK dynamic libraries<br>**Forced** to ON if `USE_GLPK=ON` **and** `BUILD_DEPS=ON`
| |
`USE_HIGHS` | ON\* | Enable HIGHS support<br>**Forced** to OFF if `BUILD_CXX=OFF`
`BUILD_HIGHS` | OFF\* | Build the HiGHS dynamic libraries<br>**Forced** to ON if `USE_HIGHS=ON` **and** `BUILD_DEPS=ON`
| |
`USE_SCIP` | ON\* | Enable SCIP support<br>**Forced** to OFF if `BUILD_CXX=OFF`
`BUILD_SCIP` | OFF\* | Build the SCIP dynamic libraries<br>**Forced** to ON if `USE_SCIP=ON` **and** `BUILD_DEPS=ON`
| |
`USE_CPLEX` | OFF | Enable CPLEX support
| |
`BUILD_DOC` | OFF\* | Build all documentations
`BUILD_CXX_DOC` | OFF\* | Build C++ documentation<br>**Forced** to ON if `BUILD_DOC=ON`
`BUILD_DOTNET_DOC` | OFF\* | Build .Net documentation<br>**Forced** to ON if `BUILD_DOC=ON`
`BUILD_JAVA_DOC` | OFF\* | Build Java documentation<br>**Forced** to ON if `BUILD_DOC=ON`
`BUILD_PYTHON_DOC` | OFF\* | Build Python documentation<br>**Forced** to ON if `BUILD_DOC=ON`
`INSTALL_DOC` | OFF\* | Install all documentations<br>**Forced** to OFF if `BUILD_CXX=OFF` or `BUILD_DOC=OFF`
| |
`BUILD_SAMPLES` | ON\* | Build all samples<br>Default to ON if `BUILD_DEPS=ON`
`BUILD_CXX_SAMPLES` | ON\* | Build all C++ samples<br>**Forced** to OFF if `BUILD_CXX=OFF` or `BUILD_SAMPLE=OFF`
`BUILD_DOTNET_SAMPLES` | ON\* | Build all .Net samples<br>**Forced** to OFF if `BUILD_DOTNET=OFF` or `BUILD_SAMPLE=OFF`
`BUILD_JAVA_SAMPLES` | ON\* | Build all Java samples<br>**Forced** to OFF if `BUILD_JAVA=OFF` or `BUILD_SAMPLE=OFF`
`BUILD_PYTHON_SAMPLES` | ON\* | Build all Python samples<br>**Forced** to OFF if `BUILD_PYTHON=OFF` or `BUILD_SAMPLE=OFF`
| |
`BUILD_EXAMPLES` | ON\* | Build all examples<br>Default to ON if `BUILD_DEPS=ON`
`BUILD_CXX_EXAMPLES` | ON\* | Build all C++ examples<br>**Forced** to OFF if `BUILD_CXX=OFF` or `BUILD_SAMPLE=OFF`
`BUILD_DOTNET_EXAMPLES` | ON\* | Build all .Net examples<br>**Forced** to OFF if `BUILD_DOTNET=OFF` or `BUILD_SAMPLE=OFF`
`BUILD_JAVA_EXAMPLES` | ON\* | Build all Java examples<br>**Forced** to OFF if `BUILD_JAVA=OFF` or `BUILD_SAMPLE=OFF`
`BUILD_PYTHON_EXAMPLES` | ON\* | Build all Python examples<br>**Forced** to OFF if `BUILD_PYTHON=OFF` or `BUILD_SAMPLE=OFF`
| |
`USE_DOTNET_46` | OFF | Enable .Net Framework 4.6 support<br>Only available if `BUILD_DOTNET=ON`
`USE_DOTNET_461` | OFF | Enable .Net Framework 4.6.1 support<br>Only available if `BUILD_DOTNET=ON`
`USE_DOTNET_462` | OFF | Enable .Net Framework 4.6.2 support<br>Only available if `BUILD_DOTNET=ON`
`USE_DOTNET_48` | OFF | Enable .Net Framework 4.8 support<br>Only available if `BUILD_DOTNET=ON`
`USE_DOTNET_STD_21` | OFF | Enable .Net Standard 2.1 support<br>Only available if `BUILD_DOTNET=ON` and not targeting arm64 platform
`USE_DOTNET_CORE_31` | OFF | Enable .Net Core 3.1 LTS support<br>Only available if `BUILD_DOTNET=ON` and not targeting arm64 platform
`USE_DOTNET_6` | OFF | Enable .Net 6 LTS support<br>Only available if `BUILD_DOTNET=ON`
`USE_DOTNET_7` | OFF | Enable .Net 7 support<br>Only available if `BUILD_DOTNET=ON`
`USE_DOTNET_8` | ON | Enable .Net 8 LTS support<br>Only available if `BUILD_DOTNET=ON`
`USE_DOTNET_9` | OFF | Enable .Net 9 support<br>Only available if `BUILD_DOTNET=ON`
`UNIVERSAL_DOTNET_PACKAGE` | OFF | Build a multi platform package (i.e. `Google.OrTools` will depends on all runtime packages)<br>Only available if `BUILD_DOTNET=ON`
| |
`SKIP_GPG` | ON | Disable GPG sign<br>Only available if `BUILD_JAVA=ON`
`UNIVERSAL_JAVA_PACKAGE` | OFF | Build a multi platform package (i.e. `ortools-java` will depends on all native packages)<br>Only available if `BUILD_JAVA=ON`
`BUILD_FAT_JAR` | OFF | Build a `ortools-java` .jar that includes all of its own Maven dependencies, including the native package<br>Only available if `BUILD_JAVA=ON`
| |
`BUILD_pybind11` | `BUILD_DEPS` | Static build the pybind11 libraries<br>**Forced** to ON if `BUILD_DEPS=ON`<br>Only available if `BUILD_PYTHON=ON`
`BUILD_pybind11_abseil` | `BUILD_DEPS` | Static build the pybind11_abseil libraries<br>**Forced** to ON if `BUILD_DEPS=ON`<br>Only available if `BUILD_PYTHON=ON`
`BUILD_pybind11_protobuf` | `BUILD_DEPS` | Static build the pybind11_protobuf libraries<br>**Forced** to ON if `BUILD_DEPS=ON`<br>Only available if `BUILD_PYTHON=ON`
`GENERATE_PYTHON_STUB` | ON | Generate python stub files<br>Only available if `BUILD_PYTHON=ON`
`BUILD_VENV` | `BUILD_TESTING` | Create python venv in `BINARY_DIR/python/venv`<br>**Forced** to ON if `BUILD_TESTING=ON`<br>Only available if `BUILD_PYTHON=ON`
`VENV_USE_SYSTEM_SITE_PACKAGES` | OFF | Python venv can use system site package (e.g. `py3-numpy` on Alpine)<br>Only available if `BUILD_PYTHON=ON` and `BUILD_VENV=ON`
`FETCH_PYTHON_DEPS` | `BUILD_DEPS` | Fetch python modules needed to build ortools package<br>Only available if `BUILD_PYTHON=ON`
| |
## Integrating OR-Tools in your CMake Project

View File

@@ -6,7 +6,7 @@ RUN apt-get update -qq \
python3-dev python3-pip \
python3-setuptools python3-wheel \
python3-venv python3-virtualenv \
python3-numpy python3-pandas \
python3-numpy python3-pandas python3-typing-extensions \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
RUN python3 -m pip install --break-system-package \

View File

@@ -36,6 +36,31 @@ filegroup(
visibility = ["//visibility:public"],
)
cc_library(
name = "accurate_sum",
hdrs = ["accurate_sum.h"],
)
cc_library(
name = "adjustable_priority_queue",
hdrs = [
"adjustable_priority_queue.h",
"adjustable_priority_queue-inl.h",
],
deps = [
":base",
],
)
cc_library(
name = "array",
srcs = ["array_internal.h"],
hdrs = ["array.h"],
deps = [
"@abseil-cpp//absl/utility",
],
)
cc_library(
name = "base",
srcs = [
@@ -82,28 +107,8 @@ cc_library(
)
cc_library(
name = "accurate_sum",
hdrs = ["accurate_sum.h"],
)
cc_library(
name = "adjustable_priority_queue",
hdrs = [
"adjustable_priority_queue.h",
"adjustable_priority_queue-inl.h",
],
deps = [
":base",
],
)
cc_library(
name = "array",
srcs = ["array_internal.h"],
hdrs = ["array.h"],
deps = [
"@abseil-cpp//absl/utility",
],
name = "base_export",
hdrs = ["base_export.h"],
)
cc_library(
@@ -137,6 +142,31 @@ cc_library(
],
)
cc_library(
name = "constant_divisor",
srcs = ["constant_divisor.cc"],
hdrs = ["constant_divisor.h"],
visibility = ["//visibility:public"],
deps = [
"@abseil-cpp//absl/log:check",
"@abseil-cpp//absl/numeric:int128",
],
)
cc_test(
name = "constant_divisor_test",
srcs = ["constant_divisor_test.cc"],
deps = [
":constant_divisor",
"@abseil-cpp//absl/flags:flag",
"@abseil-cpp//absl/random",
"@abseil-cpp//absl/random:bit_gen_ref",
"@abseil-cpp//absl/random:distributions",
"@com_google_benchmark//:benchmark",
"@com_google_googletest//:gtest_main",
],
)
cc_library(
name = "container_logging",
hdrs = ["container_logging.h"],
@@ -242,28 +272,6 @@ cc_library(
],
)
cc_library(
name = "status_matchers",
hdrs = ["status_matchers.h"],
deps = [
":base",
"@abseil-cpp//absl/status",
"@abseil-cpp//absl/status:statusor",
"@abseil-cpp//absl/strings",
"@com_google_googletest//:gtest",
],
)
cc_library(
name = "message_matchers",
hdrs = ["message_matchers.h"],
deps = [
"@abseil-cpp//absl/strings",
"@com_google_googletest//:gtest",
"@com_google_protobuf//:protobuf",
],
)
cc_library(
name = "gmock",
hdrs = ["gmock.h"],
@@ -328,30 +336,11 @@ cc_library(
name = "intops",
hdrs = ["strong_int.h"],
deps = [
":int_type",
"@abseil-cpp//absl/log:absl_log",
"@abseil-cpp//absl/numeric:int128",
"@abseil-cpp//absl/strings",
"@abseil-cpp//absl/strings:str_format",
],
)
cc_test(
name = "strong_int_test",
size = "small",
timeout = "long",
srcs = ["strong_int_test.cc"],
deps = [
":intops",
":base",
":types",
"@abseil-cpp//absl/container:node_hash_map",
"@abseil-cpp//absl/flags:marshalling",
"@abseil-cpp//absl/hash:hash_testing",
":int_type",
"@abseil-cpp//absl/log:absl_log",
"@abseil-cpp//absl/numeric:int128",
"@abseil-cpp//absl/strings",
"@abseil-cpp//absl/strings:str_format",
"@com_google_googletest//:gtest_main",
],
)
@@ -361,31 +350,6 @@ cc_library(
deps = [":base"],
)
cc_library(
name = "constant_divisor",
srcs = ["constant_divisor.cc"],
hdrs = ["constant_divisor.h"],
visibility = ["//visibility:public"],
deps = [
"@abseil-cpp//absl/log:check",
"@abseil-cpp//absl/numeric:int128",
],
)
cc_test(
name = "constant_divisor_test",
srcs = ["constant_divisor_test.cc"],
deps = [
":constant_divisor",
"@abseil-cpp//absl/flags:flag",
"@abseil-cpp//absl/random",
"@abseil-cpp//absl/random:bit_gen_ref",
"@abseil-cpp//absl/random:distributions",
"@com_google_benchmark//:benchmark",
"@com_google_googletest//:gtest_main",
],
)
cc_library(
name = "linked_hash_map",
hdrs = ["linked_hash_map.h"],
@@ -418,11 +382,6 @@ cc_library(
],
)
cc_library(
name = "base_export",
hdrs = ["base_export.h"],
)
cc_library(
name = "macros",
hdrs = ["macros.h"],
@@ -460,6 +419,16 @@ cc_library(
],
)
cc_library(
name = "message_matchers",
hdrs = ["message_matchers.h"],
deps = [
"@abseil-cpp//absl/strings",
"@com_google_googletest//:gtest",
"@com_google_protobuf//:protobuf",
],
)
cc_library(
name = "murmur",
hdrs = ["murmur.h"],
@@ -515,20 +484,6 @@ cc_library(
],
)
cc_library(
name = "temp_path",
srcs = ["temp_path.cc"],
hdrs = ["temp_path.h"],
deps = [
":base",
":file",
"@abseil-cpp//absl/log:check",
"@abseil-cpp//absl/status",
"@abseil-cpp//absl/strings",
"@abseil-cpp//absl/time",
],
)
cc_library(
name = "protobuf_util",
hdrs = ["protobuf_util.h"],
@@ -596,6 +551,18 @@ cc_library(
],
)
cc_library(
name = "status_matchers",
hdrs = ["status_matchers.h"],
deps = [
":base",
"@abseil-cpp//absl/status",
"@abseil-cpp//absl/status:statusor",
"@abseil-cpp//absl/strings",
"@com_google_googletest//:gtest",
],
)
cc_library(
name = "status_macros",
hdrs = ["status_macros.h"],
@@ -613,6 +580,36 @@ cc_library(
deps = [":base"],
)
cc_library(
name = "strong_int",
hdrs = ["strong_int.h"],
deps = [
"@abseil-cpp//absl/meta:type_traits",
"@abseil-cpp//absl/strings",
"@abseil-cpp//absl/strings:str_format",
"@abseil-cpp//absl/strings:string_view",
],
)
cc_test(
name = "strong_int_test",
size = "small",
timeout = "long",
srcs = ["strong_int_test.cc"],
deps = [
":gmock",
":logging",
":strong_int",
"@abseil-cpp//absl/container:node_hash_map",
"@abseil-cpp//absl/flags:marshalling",
"@abseil-cpp//absl/hash:hash_testing",
"@abseil-cpp//absl/numeric:int128",
"@abseil-cpp//absl/strings",
"@abseil-cpp//absl/strings:str_format",
"@com_google_googletest//:gtest_main",
],
)
cc_library(
name = "strong_vector",
hdrs = ["strong_vector.h"],
@@ -641,6 +638,20 @@ cc_library(
],
)
cc_library(
name = "temp_path",
srcs = ["temp_path.cc"],
hdrs = ["temp_path.h"],
deps = [
":base",
":file",
"@abseil-cpp//absl/log:check",
"@abseil-cpp//absl/status",
"@abseil-cpp//absl/strings",
"@abseil-cpp//absl/time",
],
)
cc_library(
name = "threadpool",
srcs = ["threadpool.cc"],

View File

@@ -14,6 +14,7 @@
#ifndef OR_TOOLS_BASE_FILE_H_
#define OR_TOOLS_BASE_FILE_H_
#include <cstddef>
#include <cstdint>
#include <string>
@@ -39,7 +40,7 @@ class File {
static File* OpenOrDie(absl::string_view file_name, absl::string_view mode);
#endif // SWIG
File(absl::string_view name);
explicit File(absl::string_view name);
virtual ~File() = default;
// Reads "size" bytes to buf from file, buff should be pre-allocated.
@@ -57,7 +58,7 @@ class File {
// Returns file size.
virtual size_t Size() = 0;
// Returns wether the file is currently open.
// Returns whether the file is currently open.
virtual bool Open() const = 0;
// Reads the whole file to a string, with a maximum length of 'max_length'.
@@ -106,8 +107,8 @@ absl::StatusOr<std::string> GetContents(absl::string_view path,
absl::Status GetContents(absl::string_view file_name, std::string* output,
Options options);
absl::Status SetContents(absl::string_view file_name, absl::string_view contents,
Options options);
absl::Status SetContents(absl::string_view file_name,
absl::string_view contents, Options options);
absl::Status WriteString(File* file, absl::string_view contents,
Options options);

View File

@@ -54,8 +54,8 @@
// For example, the below demonstrates a case where the 2 are not equivalent
// at compile time and can lead to subtle initialization bugs:
//
// DEFINE_STRONG_INT_TYPE(MyStrongInt8, int8);
// int8 foo = 1024; // Compile error: const conversion to ...
// DEFINE_STRONG_INT_TYPE(MyStrongInt8, int8_t);
// int8_t foo = 1024; // Compile error: const conversion to ...
// MyStrongInt8 foo(1024); // Compiles ok: foo has undefined / 0 value.
//
// Usage:
@@ -120,20 +120,18 @@
#ifndef OR_TOOLS_BASE_STRONG_INT_H_
#define OR_TOOLS_BASE_STRONG_INT_H_
#include <cstddef>
#include <cstdint>
#include <functional>
#include <iosfwd>
#include <iterator>
#include <limits>
#include <ostream>
#include <string>
#include <tuple>
#include <type_traits>
#include <utility>
#include "absl/base/attributes.h"
#include "absl/base/macros.h"
#include "absl/base/port.h"
#include "absl/log/absl_log.h"
#include "absl/meta/type_traits.h"
#include "absl/strings/numbers.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
@@ -178,7 +176,7 @@ struct NullStrongIntValidator {
// Verify initialization of StrongInt<T> from arg, type U.
template <typename T, typename U>
static constexpr bool ValidateInit(U arg) {
static constexpr bool ValidateInit(U /*arg*/) {
return true;
}
// Verify -value.
@@ -291,8 +289,8 @@ class StrongInt {
//
// Example: Assume you have two StrongInt types.
//
// DEFINE_STRONG_INT_TYPE(Bytes, int64);
// DEFINE_STRONG_INT_TYPE(Megabytes, int64);
// DEFINE_STRONG_INT_TYPE(Bytes, int64_t);
// DEFINE_STRONG_INT_TYPE(Megabytes, int64_t);
//
// If you want to be able to (explicitly) construct an instance of Bytes from
// an instance of Megabytes, simply define a converter function in the same
@@ -371,7 +369,7 @@ class StrongInt {
++value_;
return *this;
}
StrongInt operator++(int postfix_flag) { // x++
StrongInt operator++(int /*postfix_flag*/) { // x++
ValidatorType::template ValidateAdd<ValueType>(value_, ValueType(1));
StrongInt temp(*this);
++value_;
@@ -382,7 +380,7 @@ class StrongInt {
--value_;
return *this;
}
StrongInt operator--(int postfix_flag) { // x--
StrongInt operator--(int /*postfix_flag*/) { // x--
ValidatorType::template ValidateSubtract<ValueType>(value_, ValueType(1));
StrongInt temp(*this);
--value_;
@@ -467,7 +465,7 @@ class StrongInt {
//
// Note: The user is also able to provide a custom AbslStringify. Example:
//
// DEFINE_STRONG_INT_TYPE(MyStrongInt, int64);
// DEFINE_STRONG_INT_TYPE(MyStrongInt, int64_t);
//
// template <typename Sink>
// void AbslStringify(Sink &sink, MyStrongInt arg) { ... }
@@ -518,8 +516,6 @@ bool AbslParseFlag(absl::string_view text,
value = static_cast<ValueType>(larger_value);
}
// TODO(dploch): We shouldn't crash in flag parsing.
// Validator should be re-tooled to return meaningful values.
*out = StrongInt<TagType, ValueType, ValidatorType>(value);
return true;
}
@@ -537,8 +533,8 @@ std::ostream& operator<<(std::ostream& os,
return os << arg.value();
}
// Provide the << operator, primarily for logging purposes. Specialized for int8
// so that an integer and not a character is printed.
// Provide the << operator, primarily for logging purposes. Specialized for
// int8_t so that an integer and not a character is printed.
template <typename TagType, typename ValidatorType>
std::ostream& operator<<(std::ostream& os,
StrongInt<TagType, int8_t, ValidatorType> arg) {
@@ -546,7 +542,7 @@ std::ostream& operator<<(std::ostream& os,
}
// Provide the << operator, primarily for logging purposes. Specialized for
// uint8 so that an integer and not a character is printed.
// uint8_t so that an integer and not a character is printed.
template <typename TagType, typename ValidatorType>
std::ostream& operator<<(std::ostream& os,
StrongInt<TagType, uint8_t, ValidatorType> arg) {
@@ -695,6 +691,7 @@ StrongIntRange<IntType> MakeStrongIntRange(IntType begin, IntType end) {
// Numeric_limits override for strong int.
namespace std {
// Allow StrongInt to be used as a key to hashable containers.
// NOLINTNEXTLINE(google3-runtime-std-hash-specialization)
template <typename Tag, typename Value, typename Validator>
struct hash<util_intops::StrongInt<Tag, Value, Validator>>
: ::util_intops::StrongInt<Tag, Value, Validator>::Hasher {};

View File

@@ -1,6 +1,20 @@
// Copyright 2010-2025 Google LLC
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Unit test cases for StrongInt.
#include "ortools/base/strong_int.h"
#include <cstddef>
#include <cstdint>
#include <limits>
#include <sstream>
@@ -15,8 +29,8 @@
#include "absl/strings/str_format.h"
#include "absl/strings/substitute.h"
#include "gtest/gtest.h"
#include "ortools/base/gmock.h"
#include "ortools/base/logging.h"
#include "ortools/base/types.h"
namespace util_intops {
namespace {
@@ -94,7 +108,7 @@ TYPED_TEST(StrongIntTest, TestCtors) {
EXPECT_EQ(V(76), y.value());
}
{ // Test construction from int8.
{ // Test construction from int8_t.
constexpr int8_t i = 93;
T x(i);
EXPECT_EQ(V(93), x.value());
@@ -106,13 +120,13 @@ TYPED_TEST(StrongIntTest, TestCtors) {
EXPECT_EQ(V(-76), y.value());
}
{ // Test construction from uint8.
{ // Test construction from uint8_t.
uint8_t i = 93;
T x(i);
EXPECT_EQ(V(93), x.value());
}
{ // Test construction from int16.
{ // Test construction from int16_t.
int16_t i = 93;
T x(i);
EXPECT_EQ(V(93), x.value());
@@ -122,13 +136,13 @@ TYPED_TEST(StrongIntTest, TestCtors) {
EXPECT_EQ(V(-76), y.value());
}
{ // Test construction from uint16.
{ // Test construction from uint16_t.
uint16_t i = 93;
T x(i);
EXPECT_EQ(V(93), x.value());
}
{ // Test construction from int32.
{ // Test construction from int32_t.
int32_t i = 93;
T x(i);
EXPECT_EQ(V(93), x.value());
@@ -138,13 +152,13 @@ TYPED_TEST(StrongIntTest, TestCtors) {
EXPECT_EQ(V(-76), y.value());
}
{ // Test construction from uint32.
{ // Test construction from uint32_t.
uint32_t i = 93;
T x(i);
EXPECT_EQ(V(93), x.value());
}
{ // Test construction from int64.
{ // Test construction from int64_t.
int64_t i = 93;
T x(i);
EXPECT_EQ(V(93), x.value());
@@ -154,7 +168,7 @@ TYPED_TEST(StrongIntTest, TestCtors) {
EXPECT_EQ(V(-76), y.value());
}
{ // Test construction from uint64.
{ // Test construction from uint64_t.
uint64_t i = 93;
T x(i);
EXPECT_EQ(V(93), x.value());
@@ -167,7 +181,7 @@ TYPED_TEST(StrongIntTest, TestCtors) {
EXPECT_EQ(V(93), x.value());
// It is undefined to init an unsigned int from a negative float.
if (std::numeric_limits<V>::is_signed) {
if constexpr (std::numeric_limits<V>::is_signed) {
float j = -76.1;
T y(j);
EXPECT_EQ(V(-76.1), y.value());
@@ -180,7 +194,7 @@ TYPED_TEST(StrongIntTest, TestCtors) {
EXPECT_EQ(V(93), x.value());
// It is undefined to init an unsigned int from a negative double.
if (std::numeric_limits<V>::is_signed) {
if constexpr (std::numeric_limits<V>::is_signed) {
double j = -76.1;
T y(j);
EXPECT_EQ(V(-76.1), y.value());
@@ -193,7 +207,7 @@ TYPED_TEST(StrongIntTest, TestCtors) {
EXPECT_EQ(V(93), x.value());
// It is undefined to init an unsigned int from a negative long double.
if (std::numeric_limits<V>::is_signed) {
if constexpr (std::numeric_limits<V>::is_signed) {
long double j = -76.1;
T y(j);
EXPECT_EQ(V(-76.1), y.value());
@@ -298,7 +312,7 @@ TYPED_TEST(StrongIntTest, TestAbslParseFlagInvalid) {
T t;
std::string error;
if (std::numeric_limits<V>::is_signed) {
if constexpr (std::numeric_limits<V>::is_signed) {
EXPECT_DEATH(absl::ParseFlag("-123", &t, &error), "PositiveValidator");
} else {
EXPECT_FALSE(absl::ParseFlag("-123", &t, &error));
@@ -309,7 +323,7 @@ TYPED_TEST(StrongIntTest, TestAbslParseFlagInvalid) {
TYPED_TEST(StrongIntTest, TestCtorDeath) {
using V = typename TestFixture::V;
if (std::numeric_limits<V>::is_signed) {
if constexpr (std::numeric_limits<V>::is_signed) {
struct CustomTag {};
using T = StrongInt<CustomTag, V, PositiveValidator>;
EXPECT_DEATH(T(static_cast<V>(-123)), "PositiveValidator");
@@ -392,14 +406,6 @@ TYPED_TEST(StrongIntTest, TestAssignmentOperator) {
EXPECT_EQ(y.value(), (x = y).value());
EXPECT_EQ(y.value(), x.value());
}
#if 0 // These should fail to compile.
{
T x(12);
x = 34; // Can't assign from int.
x = V(34); // Can't assign from ValueType.
x = 34.0; // Can't assign from double.
}
#endif
}
#define TEST_T_OP_T(xval, op, yval) \
@@ -436,18 +442,6 @@ TYPED_TEST(StrongIntTest, TestPlusOperators) {
TEST_T_OP_T(-9, +, -3)
// Test addition by zero.
TEST_T_OP_T(93, +, 0);
#if 0 // These should fail to compile.
{
T x(9);
x + 3; // Can't operate on int.
x += 3;
x + V(3); // Can't operate on ValueType.
x += V(3);
x + 3.0; // Can't operate on double.
x += 3.0;
}
#endif
}
TYPED_TEST(StrongIntTest, TestMinusOperators) {
@@ -468,18 +462,6 @@ TYPED_TEST(StrongIntTest, TestMinusOperators) {
TEST_T_OP_T(93, -, 0);
// Test subtraction from zero.
TEST_T_OP_T(0, -, 93);
#if 0 // These should fail to compile.
{
T x(9);
x - 3; // Can't operate on int.
x -= 3;
x - V(3); // Can't operate on ValueType.
x -= V(3);
x - 3.0; // Can't operate on double.
x -= 3.0;
}
#endif
}
#define TEST_T_OP_NUM(xval, op, numtype, yval) \
@@ -519,6 +501,7 @@ TYPED_TEST(StrongIntTest, TestMinusOperators) {
} \
}
// NOLINTNEXTLINE: google-readability-function-size
TYPED_TEST(StrongIntTest, TestMultiplyOperators) {
using T = typename TestFixture::T;
using V = typename TestFixture::V;
@@ -526,7 +509,7 @@ TYPED_TEST(StrongIntTest, TestMultiplyOperators) {
// Test positive vs. positive multiplication.
TEST_T_OP_NUM(9, *, V, 3);
TEST_NUM_OP_T(V, 9, *, 3);
if (std::is_signed<V>::value) {
if constexpr (std::is_signed<V>::value) {
// Test negative vs. positive multiplication.
TEST_T_OP_NUM(-9, *, V, 3);
TEST_NUM_OP_T(V, -9, *, 3);
@@ -543,33 +526,33 @@ TYPED_TEST(StrongIntTest, TestMultiplyOperators) {
// Test multiplication by zero.
TEST_T_OP_NUM(93, *, V, 0);
TEST_NUM_OP_T(V, 93, *, 0);
if (std::is_signed<V>::value) {
if constexpr (std::is_signed<V>::value) {
// Test multiplication by a negative.
TEST_T_OP_NUM(93, *, V, -1);
TEST_NUM_OP_T(V, 93, *, -1);
}
// Test multiplication by int8.
// Test multiplication by int8_t.
TEST_T_OP_NUM(39, *, int8_t, 2);
TEST_NUM_OP_T(int8_t, 39, *, 2);
// Test multiplication by uint8.
// Test multiplication by uint8_t.
TEST_T_OP_NUM(39, *, uint8_t, 2);
TEST_NUM_OP_T(uint8_t, 39, *, 2);
// Test multiplication by int16.
// Test multiplication by int16_t.
TEST_T_OP_NUM(39, *, int16_t, 2);
TEST_NUM_OP_T(int16_t, 39, *, 2);
// Test multiplication by uint16.
// Test multiplication by uint16_t.
TEST_T_OP_NUM(39, *, uint16_t, 2);
TEST_NUM_OP_T(uint16_t, 39, *, 2);
// Test multiplication by int32.
// Test multiplication by int32_t.
TEST_T_OP_NUM(39, *, int32_t, 2);
TEST_NUM_OP_T(int32_t, 39, *, 2);
// Test multiplication by uint32.
// Test multiplication by uint32_t.
TEST_T_OP_NUM(39, *, uint32_t, 2);
TEST_NUM_OP_T(uint32_t, 39, *, 2);
// Test multiplication by int64.
// Test multiplication by int64_t.
TEST_T_OP_NUM(39, *, int64_t, 2);
TEST_NUM_OP_T(int64_t, 39, *, 2);
// Test multiplication by uint64.
// Test multiplication by uint64_t.
TEST_T_OP_NUM(39, *, uint64_t, 2);
TEST_NUM_OP_T(uint64_t, 39, *, 2);
if constexpr (std::is_fundamental_v<V>) {
@@ -583,14 +566,6 @@ TYPED_TEST(StrongIntTest, TestMultiplyOperators) {
TEST_T_OP_NUM(39, *, long double, 2.1);
TEST_NUM_OP_T(long double, 39, *, 2.1);
}
#if 0 // These should fail to compile.
{
T x(9);
x * T(3); // Can't operate on IntType.
x *= T(3);
}
#endif
}
TYPED_TEST(StrongIntTest, TestDivideOperators) {
@@ -599,31 +574,35 @@ TYPED_TEST(StrongIntTest, TestDivideOperators) {
// Test positive vs. positive division.
TEST_T_OP_NUM(9, /, V, 3);
// Test negative vs. positive division.
TEST_T_OP_NUM(-9, /, V, 3);
// Test positive vs. negative division.
TEST_T_OP_NUM(9, /, V, -3);
// Test negative vs. negative division.
TEST_T_OP_NUM(-9, /, V, -3);
if constexpr (std::is_signed<V>::value) {
// Test negative vs. positive division.
TEST_T_OP_NUM(-9, /, V, 3);
// Test positive vs. negative division.
TEST_T_OP_NUM(9, /, V, -3);
// Test negative vs. negative division.
TEST_T_OP_NUM(-9, /, V, -3);
}
// Test division by one.
TEST_T_OP_NUM(93, /, V, 1);
// Test division by a negative.
TEST_T_OP_NUM(93, /, V, -1);
// Test division by int8.
if constexpr (std::is_signed<V>::value) {
// Test division by a negative.
TEST_T_OP_NUM(93, /, V, -1);
}
// Test division by int8_t.
TEST_T_OP_NUM(93, /, int8_t, 2);
// Test division by uint8.
// Test division by uint8_t.
TEST_T_OP_NUM(93, /, uint8_t, 2);
// Test division by int16.
// Test division by int16_t.
TEST_T_OP_NUM(93, /, int16_t, 2);
// Test division by uint16.
// Test division by uint16_t.
TEST_T_OP_NUM(93, /, uint16_t, 2);
// Test division by int32.
// Test division by int32_t.
TEST_T_OP_NUM(93, /, int32_t, 2);
// Test division by uint32.
// Test division by uint32_t.
TEST_T_OP_NUM(93, /, uint32_t, 2);
// Test division by int64.
// Test division by int64_t.
TEST_T_OP_NUM(93, /, int64_t, 2);
// Test division by uint64.
// Test division by uint64_t.
TEST_T_OP_NUM(93, /, uint64_t, 2);
if constexpr (std::is_fundamental_v<V>) {
// Test division by float.
@@ -633,14 +612,6 @@ TYPED_TEST(StrongIntTest, TestDivideOperators) {
// Test division by long double.
TEST_T_OP_NUM(93, /, long double, 2.1);
}
#if 0 // These should fail to compile.
{
T x(9);
x / T(3); // Can't operate on IntType.
x /= T(3);
}
#endif
}
TYPED_TEST(StrongIntTest, TestModuloOperators) {
@@ -659,34 +630,24 @@ TYPED_TEST(StrongIntTest, TestModuloOperators) {
TEST_T_OP_NUM(93, %, V, 1);
// Test modulo by a negative.
TEST_T_OP_NUM(93, %, V, -5);
// Test modulo by int8.
// Test modulo by int8_t.
TEST_T_OP_NUM(93, %, int8_t, 5);
// Test modulo by uint8.
// Test modulo by uint8_t.
TEST_T_OP_NUM(93, %, uint8_t, 5);
// Test modulo by int16.
// Test modulo by int16_t.
TEST_T_OP_NUM(93, %, int16_t, 5);
// Test modulo by uint16.
// Test modulo by uint16_t.
TEST_T_OP_NUM(93, %, uint16_t, 5);
// Test modulo by int32.
// Test modulo by int32_t.
TEST_T_OP_NUM(93, %, int32_t, 5);
// Test modulo by uint32.
// Test modulo by uint32_t.
TEST_T_OP_NUM(93, %, uint32_t, 5);
// Test modulo by int64.
// Test modulo by int64_t.
TEST_T_OP_NUM(93, %, int64_t, 5);
// Test modulo by uint64.
// Test modulo by uint64_t.
TEST_T_OP_NUM(93, %, uint64_t, 5);
// Test modulo by a larger value.
TEST_T_OP_NUM(93, %, V, 100);
#if 0 // These should fail to compile.
{
T x(9);
x % T(3); // Can't operate on IntType.
x %= T(3);
x % 3.0; // Can't operate on float.
x %= 3.0;
}
#endif
}
TYPED_TEST(StrongIntTest, TestLeftShiftOperators) {
@@ -697,16 +658,6 @@ TYPED_TEST(StrongIntTest, TestLeftShiftOperators) {
TEST_T_OP_NUM(0x09, <<, int, 3);
// Test shift by zero.
TEST_T_OP_NUM(0x09, <<, int, 0);
#if 0 // These should fail to compile.
{
T x(9);
x << T(3); // Can't operate on IntType.
x <<= T(3);
x << 3.0; // Can't operate on float.
x <<= 3.0;
}
#endif
}
TYPED_TEST(StrongIntTest, TestRightShiftOperators) {
@@ -717,16 +668,6 @@ TYPED_TEST(StrongIntTest, TestRightShiftOperators) {
TEST_T_OP_NUM(0x09, >>, int, 3);
// Test shift by zero.
TEST_T_OP_NUM(0x09, >>, int, 0);
#if 0 // These should fail to compile.
{
T x(9);
x >> T(3); // Can't operate on IntType.
x >>= T(3);
x >> 3.0; // Can't operate on float.
x >>= 3.0;
}
#endif
}
TYPED_TEST(StrongIntTest, TestBitAndOperators) {
@@ -737,16 +678,6 @@ TYPED_TEST(StrongIntTest, TestBitAndOperators) {
TEST_T_OP_T(0x09, &, 0x03);
// Test bit-and by zero.
TEST_T_OP_T(0x09, &, 0x00);
#if 0 // These should fail to compile.
{
T x(9);
x & 3; // Can't operate on int.
x &= 3;
x & 3.0; // Can't operate on float.
x &= 3.0;
}
#endif
}
TYPED_TEST(StrongIntTest, TestBitOrOperators) {
@@ -757,16 +688,6 @@ TYPED_TEST(StrongIntTest, TestBitOrOperators) {
TEST_T_OP_T(0x09, |, 0x03);
// Test bit-or by zero.
TEST_T_OP_T(0x09, |, 0x00);
#if 0 // These should fail to compile.
{
T x(9);
x | 3; // Can't operate on int.
x |= 3;
x | 3.0; // Can't operate on float.
x |= 3.0;
}
#endif
}
TYPED_TEST(StrongIntTest, TestBitXorOperators) {
@@ -777,16 +698,6 @@ TYPED_TEST(StrongIntTest, TestBitXorOperators) {
TEST_T_OP_T(0x09, ^, 0x03);
// Test bit-xor by zero.
TEST_T_OP_T(0x09, ^, 0x00);
#if 0 // These should fail to compile.
{
T x(9);
x ^ 3; // Can't operate on int.
x ^= 3;
x ^ 3.0; // Can't operate on float.
x ^= 3.0;
}
#endif
}
TYPED_TEST(StrongIntTest, TestComparisonOperators) {
@@ -1066,7 +977,7 @@ struct StrongIntTestHelper {
template <typename U, typename = typename std::enable_if<
std::is_constructible<StrongInt<void, T>, U>::value,
void>::type>
StrongIntTestHelper(U x) {} // NOLINT
StrongIntTestHelper(U /*x*/) {} // NOLINT
};
static_assert(!std::is_convertible<void, StrongIntTestHelper<int>>::value, "");

View File

@@ -405,9 +405,6 @@ message GlopParameters {
optional int32 random_seed = 43 [default = 1];
// Whether to use absl::BitGen instead of MTRandom.
// MOE:begin_strip
// Note that in unit tests if this field is not explicitly set it will be
// default to true. MOE:end_strip
optional bool use_absl_random = 72 [default = false];
// Number of threads in the OMP parallel sections. If left to 1, the code will

View File

@@ -727,13 +727,12 @@ TYPED_TEST(GenericGraphInterfaceTest, GraphWithNodesButNoArc) {
EXPECT_EQ(ArcIndex(0), graph.num_arcs());
int count = 0;
for (const NodeIndex node : graph.AllNodes()) {
for (const __attribute__((unused)) ArcIndex arc :
graph.OutgoingArcs(node)) {
for ([[maybe_unused]] const ArcIndex arc : graph.OutgoingArcs(node)) {
++count;
}
}
EXPECT_EQ(0, count);
for (const __attribute__((unused)) ArcIndex arc : graph.AllForwardArcs()) {
for ([[maybe_unused]] const ArcIndex arc : graph.AllForwardArcs()) {
++count;
}
EXPECT_EQ(0, count);
@@ -919,11 +918,7 @@ TEST(CompleteGraphTest, NonEmptyGraph) {
for (const auto arc : graph.OutgoingArcs(node)) {
EXPECT_EQ(node, graph.Tail(arc));
++count;
for (const auto arc_from_tail :
graph.OutgoingArcsStartingFrom(node, arc)) {
EXPECT_EQ(arc_from_tail, arc);
break;
}
EXPECT_EQ(*(graph.OutgoingArcsStartingFrom(node, arc).begin()), arc);
}
EXPECT_EQ(kNumNodes, count);
count = 0;
@@ -940,10 +935,7 @@ TEST(CompleteBipartiteGraphTest, EmptyGraph) {
EXPECT_EQ(0, graph.num_nodes());
EXPECT_EQ(0, graph.size());
EXPECT_EQ(0, graph.num_arcs());
for (const auto arc : graph.AllForwardArcs()) {
EXPECT_TRUE(false);
EXPECT_TRUE(graph.IsArcValid(arc));
}
EXPECT_TRUE(graph.AllForwardArcs().empty());
}
TEST(CompleteBipartiteGraphTest, OneRightNodeGraph) {
@@ -980,11 +972,7 @@ TEST(CompleteBipartiteGraphTest, NonEmptyGraph) {
EXPECT_EQ(node, graph.Tail(arc));
EXPECT_EQ(kNumLeftNodes + count, graph.Head(arc));
++count;
for (const auto arc_from_tail :
graph.OutgoingArcsStartingFrom(node, arc)) {
EXPECT_EQ(arc_from_tail, arc);
break;
}
EXPECT_EQ(*(graph.OutgoingArcsStartingFrom(node, arc).begin()), arc);
}
EXPECT_EQ(node < kNumLeftNodes ? kNumRightNodes : 0, count);
count = 0;

View File

@@ -33,6 +33,6 @@ target_link_libraries(${NAME} PRIVATE
absl::strings
absl::str_format
protobuf::libprotobuf
$<$<BOOL:${USE_SCIP}>:libscip>
SCIP::libscip
${PROJECT_NAMESPACE}::ortools_proto)
#add_library(${PROJECT_NAMESPACE}::gscip ALIAS ${NAME})

View File

@@ -147,6 +147,8 @@ class MPModelProtoExporter {
// error (for example, var_index is out of range).
bool WriteLpTerm(int var_index, double coefficient,
std::string* output) const;
bool WriteLpQuadraticTerm(int var1_index, int var2_index, double coefficient,
std::string* output) const;
// Appends a pair name, value to "output", formatted to comply with the MPS
// standard.
@@ -456,6 +458,30 @@ bool MPModelProtoExporter::WriteLpTerm(int var_index, double coefficient,
return true;
}
bool MPModelProtoExporter::WriteLpQuadraticTerm(int var1_index, int var2_index,
double coefficient,
std::string* output) const {
output->clear();
if (var1_index < 0 || var1_index >= proto_.variable_size()) {
LOG(DFATAL) << "Reference to out-of-bounds variable index # " << var1_index;
return false;
}
if (var2_index < 0 || var2_index >= proto_.variable_size()) {
LOG(DFATAL) << "Reference to out-of-bounds variable index # " << var2_index;
return false;
}
auto variable_product =
var1_index == var2_index
? absl::StrCat(exported_variable_names_[var1_index], "^2")
: absl::StrCat(exported_variable_names_[var1_index], " * ",
exported_variable_names_[var2_index]);
if (coefficient != 0.0) {
*output = absl::StrCat(DoubleToStringWithForcedSign(coefficient), " ",
variable_product, " ");
}
return true;
}
namespace {
bool IsBoolean(const MPVariableProto& var) {
return var.is_integer() && ceil(var.lower_bound()) == 0.0 &&
@@ -572,6 +598,24 @@ bool MPModelProtoExporter::ExportModelAsLpFormat(
obj_line_breaker.Append(term);
show_variable[var_index] = coeff != 0.0 || show_variable[var_index];
}
if (proto_.has_quadratic_objective()) {
obj_line_breaker.Append(" + [ ");
for (int i_term = 0;
i_term < proto_.quadratic_objective().qvar1_index_size(); ++i_term) {
const int qvar1 = proto_.quadratic_objective().qvar1_index(i_term);
const int qvar2 = proto_.quadratic_objective().qvar2_index(i_term);
const double coeff = proto_.quadratic_objective().coefficient(i_term);
std::string term;
if (!WriteLpQuadraticTerm(qvar1, qvar2, 2 * coeff, &term)) {
return false;
}
obj_line_breaker.Append(term);
show_variable[qvar1] = coeff != 0.0 || show_variable[qvar1];
show_variable[qvar2] = coeff != 0.0 || show_variable[qvar2];
}
obj_line_breaker.Append(" ] / 2");
}
// Linear Constraints
absl::StrAppend(output, obj_line_breaker.GetOutput(), "\nSubject to\n");
for (int cst_index = 0; cst_index < proto_.constraint_size(); ++cst_index) {

View File

@@ -134,33 +134,33 @@ public sealed class CpSolver : IDisposable
{
switch (expr)
{
case LinearExprBuilder a:
constant += coefficient * a.Offset;
if (coefficient == 1)
{
foreach (var sub in a.Terms)
case LinearExprBuilder a:
constant += coefficient * a.Offset;
if (coefficient == 1)
{
_terms.Enqueue(sub);
foreach (var sub in a.Terms)
{
_terms.Enqueue(sub);
}
}
}
else
{
foreach (var sub in a.Terms)
else
{
_terms.Enqueue(new Term(sub.expr, sub.coefficient * coefficient));
foreach (var sub in a.Terms)
{
_terms.Enqueue(new Term(sub.expr, sub.coefficient * coefficient));
}
}
}
break;
case IntVar intVar:
var index = intVar.GetIndex();
var value = index >= 0 ? Response!.Solution[index] : -Response!.Solution[-index - 1];
constant += coefficient * value;
break;
case NotBoolVar:
throw new ArgumentException("Cannot evaluate a literal in an integer expression.");
default:
throw new ArgumentException("Cannot evaluate '" + expr + "' in an integer expression");
break;
case IntVar intVar:
var index = intVar.GetIndex();
var value = index >= 0 ? Response!.Solution[index] : -Response!.Solution[-index - 1];
constant += coefficient * value;
break;
case NotBoolVar:
throw new ArgumentException("Cannot evaluate a literal in an integer expression.");
default:
throw new ArgumentException("Cannot evaluate '" + expr + "' in an integer expression");
}
if (!_terms.TryDequeue(out var term))
@@ -170,7 +170,8 @@ public sealed class CpSolver : IDisposable
expr = term.expr;
coefficient = term.coefficient;
} while (true);
}
while (true);
return constant;
}
@@ -249,6 +250,7 @@ class BestBoundCallbackDelegate : BestBoundCallback
public BestBoundCallbackDelegate(DoubleToVoidDelegate del) => _delegate = del;
public override void NewBestBound(double bound) => _delegate(bound);
}
} // namespace Google.OrTools.Sat

View File

@@ -13,7 +13,7 @@
exports_files([
"abseil-cpp-20250127.1.patch",
"highs-v1.9.0.patch",
"highs-v1.10.patch",
"protobuf-v30.2.patch",
"pybind11_bazel.patch",
"pybind11_abseil.patch",