Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ AccessModifierOffset: -4
ColumnLimit: 100

Language: Cpp
Standard: c++17
Standard: c++20
AlignAfterOpenBracket: Align
AlignEscapedNewlines: Right
AllowAllArgumentsOnNextLine: false
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ concurrency:
env:
OPTREE_CXX_WERROR: "OFF"
_GLIBCXX_USE_CXX11_ABI: "1"
MACOSX_DEPLOYMENT_TARGET: "15.0"
IPHONEOS_DEPLOYMENT_TARGET: "16.3"
PYTHONUNBUFFERED: "1"
PYTHON_TAG: "py3" # to be updated
PYTHON_VERSION: "3" # to be updated
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ jobs:
run: make clang-format

- name: clang-tidy
run: make clang-tidy CMAKE_CXX_STANDARD=17
run: make clang-tidy CMAKE_CXX_STANDARD=20

- name: cpplint
run: make cpplint
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/tests-with-pydebug.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ env:
CMAKE_BUILD_TYPE: "Debug"
OPTREE_CXX_WERROR: "ON"
_GLIBCXX_USE_CXX11_ABI: "1"
MACOSX_DEPLOYMENT_TARGET: "15.0"
PYTHONUNBUFFERED: "1"
PYTHON: "python" # to be updated
PYTHON_TAG: "py3" # to be updated
Expand Down
32 changes: 1 addition & 31 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ env:
CMAKE_BUILD_TYPE: "Debug"
OPTREE_CXX_WERROR: "ON"
_GLIBCXX_USE_CXX11_ABI: "1"
MACOSX_DEPLOYMENT_TARGET: "15.0"
FULL_TEST_PYTHON_VERSIONS: "3.12;3.13"
PYTHONUNBUFFERED: "1"
PYTHON: "python" # to be updated
Expand Down Expand Up @@ -194,37 +195,6 @@ jobs:
echo "::endgroup::"
echo "pybind11_VERSION=HEAD" | tee -a "${GITHUB_ENV}"

- name: Test installable with C++17
shell: bash
if: runner.os != 'Windows'
run: |
(
set -ex
${{ env.PYTHON }} -m venv venv
source venv/bin/activate
OPTREE_CXX_WERROR=OFF CMAKE_CXX_STANDARD=17 \
${{ env.PYTHON }} -m pip install -v .
pushd tests
${{ env.PYTHON }} -X dev -Walways -Werror -c 'import optree'
popd
rm -rf venv
)

if [[ "$?" -ne 0 ]]; then
echo "::error::Failed to install with C++17." >&2
exit 1
fi
CORE_DUMP_FILES="$(
find . -type d -path "./venv" -prune \
-o '(' -iname "core.*.[1-9]*" -o -iname "core_*.dmp" ')' -print
)"
if [[ -n "${CORE_DUMP_FILES}" ]]; then
echo "::error::Coredump files found, indicating a crash during tests." >&2
echo "Coredump files:" >&2
ls -alh ${CORE_DUMP_FILES} >&2
exit 1
fi

- name: Test buildable without Python frontend
if: runner.os != 'Windows'
run: |
Expand Down
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ endif()
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 20) # for likely/unlikely attributes
endif()
if (CMAKE_CXX_STANDARD VERSION_LESS 17)
message(FATAL_ERROR "C++17 or higher is required")
if (CMAKE_CXX_STANDARD VERSION_LESS 20)
message(FATAL_ERROR "C++20 or higher is required")
endif()
set(CMAKE_CXX_STANDARD_REQUIRED ON)
message(STATUS "Use C++ standard: C++${CMAKE_CXX_STANDARD}")
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ The following options are available while building the Python C extension from t
```bash
export CMAKE_COMMAND="/path/to/custom/cmake"
export CMAKE_BUILD_TYPE="Debug"
export CMAKE_CXX_STANDARD="20" # C++17 is tested on Linux/macOS (C++20 is required on Windows)
export CMAKE_CXX_STANDARD="20"
export OPTREE_CXX_WERROR="OFF"
export _GLIBCXX_USE_CXX11_ABI="1"
export pybind11_DIR="/path/to/custom/pybind11"
Expand Down
64 changes: 29 additions & 35 deletions include/optree/exceptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,44 +17,46 @@ limitations under the License.

#pragma once

#include <cstddef> // std::size_t
#include <optional> // std::optional, std::nullopt
#include <sstream> // std::ostringstream
#include <stdexcept> // std::logic_error
#include <string> // std::string, std::char_traits, std::to_string
#include <type_traits> // std::declval, std::void_t, std::{true,false}_type
#include <cstddef> // std::size_t
#include <format> // std::format
#include <source_location> // std::source_location
#include <stdexcept> // std::logic_error
#include <string> // std::string, std::char_traits, std::to_string
#include <string_view> // std::string_view
#include <type_traits> // std::declval, std::void_t, std::{true,false}_type

namespace optree {

constexpr std::size_t CURRENT_FILE_PATH_SIZE = std::char_traits<char>::length(__FILE__);
constexpr std::size_t CURRENT_FILE_PATH_SIZE =
std::char_traits<char>::length(std::source_location::current().file_name());
constexpr std::size_t CURRENT_FILE_RELPATH_FROM_PROJECT_ROOT_SIZE =
std::char_traits<char>::length("include/optree/exceptions.h");
static_assert(CURRENT_FILE_PATH_SIZE >= CURRENT_FILE_RELPATH_FROM_PROJECT_ROOT_SIZE,
"SOURCE_PATH_PREFIX_SIZE must be greater than 0.");
constexpr std::size_t SOURCE_PATH_PREFIX_SIZE =
CURRENT_FILE_PATH_SIZE - CURRENT_FILE_RELPATH_FROM_PROJECT_ROOT_SIZE;
// NOLINTNEXTLINE[bugprone-reserved-identifier]
#define __FILE_RELPATH_FROM_PROJECT_ROOT__ ((const char *)&(__FILE__[SOURCE_PATH_PREFIX_SIZE]))

constexpr std::string_view RelpathFromProjectRoot(const std::string_view &abspath) {
return abspath.substr(SOURCE_PATH_PREFIX_SIZE);
}
constexpr std::string_view RelpathFromProjectRoot(
const std::source_location &source_location = std::source_location::current()) {
return RelpathFromProjectRoot(source_location.file_name());
}

class InternalError : public std::logic_error {
public:
explicit InternalError(const std::string &message) noexcept(noexcept(std::logic_error{message}))
: std::logic_error{message} {}
explicit InternalError(const std::string &message,
const std::string &file,
const std::size_t &lineno,
const std::optional<std::string> function =
std::nullopt) noexcept(noexcept(std::logic_error{message}))
: InternalError([&message, &file, &lineno, &function]() -> std::string {
std::ostringstream oss{};
oss << message << " (";
if (function) [[likely]] {
oss << "function `" << *function << "` ";
}
oss << "at file " << file << ":" << lineno << ")\n\n"
<< "Please file a bug report at https://github.com/metaopt/optree/issues.";
return oss.str();
}()) {}
explicit InternalError(
const std::string_view &message,
const std::source_location &source_location = std::source_location::current())
: std::logic_error{
std::format("{} (in function `{}` at file {}:{}:{})\n\n"
"Please file a bug report at https://github.com/metaopt/optree/issues.",
message,
source_location.function_name(),
RelpathFromProjectRoot(source_location),
source_location.line(),
source_location.column())} {}
};

} // namespace optree
Expand Down Expand Up @@ -84,16 +86,8 @@ inline std::string try_to_string([[maybe_unused]] const T &value) {
#define VA_FUNC2_(__0, __1, NAME, ...) NAME
#define VA_FUNC3_(__0, __1, __2, NAME, ...) NAME

#if !defined(__GNUC__)
# define __PRETTY_FUNCTION__ std::nullopt // NOLINT[bugprone-reserved-identifier]
#endif

#define INTERNAL_ERROR0_() INTERNAL_ERROR1_("Unreachable code.")
#define INTERNAL_ERROR1_(message) \
throw optree::InternalError((message), \
__FILE_RELPATH_FROM_PROJECT_ROOT__, \
__LINE__, \
__PRETTY_FUNCTION__)
#define INTERNAL_ERROR1_(message) throw optree::InternalError(message)
#define INTERNAL_ERROR(...) \
VA_FUNC2_(__0 __VA_OPT__(, ) __VA_ARGS__, INTERNAL_ERROR1_, INTERNAL_ERROR0_)(__VA_ARGS__)

Expand Down
Loading
Loading