Skip to content

Commit

Permalink
chore: add more noexcept qualifiers
Browse files Browse the repository at this point in the history
  • Loading branch information
XuehaiPan committed Oct 2, 2024
1 parent e9422fd commit 2361e5f
Show file tree
Hide file tree
Showing 8 changed files with 37 additions and 26 deletions.
9 changes: 5 additions & 4 deletions include/critical_section.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ class scoped_critical_section {
}
}
#else
explicit scoped_critical_section(const py::handle& /*unused*/) {}
~scoped_critical_section() = default;
explicit scoped_critical_section(const py::handle& /*unused*/) noexcept {}
~scoped_critical_section() noexcept = default;
#endif

scoped_critical_section(const scoped_critical_section&) = delete;
Expand Down Expand Up @@ -88,8 +88,9 @@ class scoped_critical_section2 {
}
}
#else
explicit scoped_critical_section2(const py::handle& /*unused*/, const py::handle& /*unused*/) {}
~scoped_critical_section2() = default;
explicit scoped_critical_section2(const py::handle& /*unused*/,
const py::handle& /*unused*/) noexcept {}
~scoped_critical_section2() noexcept = default;
#endif

scoped_critical_section2(const scoped_critical_section2&) = delete;
Expand Down
5 changes: 3 additions & 2 deletions include/exceptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,11 @@ namespace optree {

class InternalError : public std::logic_error {
public:
explicit InternalError(const std::string& msg) : std::logic_error{msg} {}
explicit InternalError(const std::string& msg) noexcept(noexcept(std::logic_error{msg}))
: std::logic_error{msg} {}
explicit InternalError(const std::string& msg,
const std::string& file,
const std::size_t& lineno)
const std::size_t& lineno) noexcept(noexcept(std::logic_error{msg}))
: InternalError([&msg, &file, &lineno]() -> std::string {
std::ostringstream oss{};
oss << msg << " (at file " << file << ":" << lineno << ")\n\n"
Expand Down
33 changes: 20 additions & 13 deletions include/hashing.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,62 +30,69 @@ namespace py = pybind11;

// boost::hash_combine
template <class T>
inline Py_ALWAYS_INLINE void HashCombine(py::size_t& seed, // NOLINT[runtime/references]
const T& v) {
inline constexpr Py_ALWAYS_INLINE void HashCombine(
py::size_t& seed, // NOLINT[runtime/references]
const T& v) noexcept(noexcept(std::hash<T>{}(v))) {
// NOLINTNEXTLINE[cppcoreguidelines-avoid-magic-numbers]
seed ^= (std::hash<T>{}(v) + 0x9E3779B9 + (seed << 6) + (seed >> 2));
}
template <class T>
inline Py_ALWAYS_INLINE void HashCombine(py::ssize_t& seed, // NOLINT[runtime/references]
const T& v) {
inline constexpr Py_ALWAYS_INLINE void HashCombine(
py::ssize_t& seed, // NOLINT[runtime/references]
const T& v) noexcept(noexcept(std::hash<T>{}(v))) {
// NOLINTNEXTLINE[cppcoreguidelines-avoid-magic-numbers]
seed ^= (std::hash<T>{}(v) + 0x9E3779B9 + (seed << 6) + (seed >> 2));
}

template <>
struct std::equal_to<py::handle> {
using is_transparent = void;
inline Py_ALWAYS_INLINE bool operator()(const py::handle& lhs, const py::handle& rhs) const {
inline constexpr Py_ALWAYS_INLINE bool operator()(const py::handle& lhs,
const py::handle& rhs) const noexcept {
return lhs.is(rhs);
}
};
template <>
struct std::not_equal_to<py::handle> {
using is_transparent = void;
inline Py_ALWAYS_INLINE bool operator()(const py::handle& lhs, const py::handle& rhs) const {
inline constexpr Py_ALWAYS_INLINE bool operator()(const py::handle& lhs,
const py::handle& rhs) const noexcept {
return !lhs.is(rhs);
}
};
template <>
struct std::hash<py::handle> {
using is_transparent = void;
inline Py_ALWAYS_INLINE std::size_t operator()(const py::handle& handle) const {
return std::hash<PyObject*>{}(handle.ptr());
inline constexpr Py_ALWAYS_INLINE std::size_t operator()(const py::handle& obj) const noexcept {
return std::hash<PyObject*>{}(obj.ptr());
}
};

template <>
struct std::equal_to<std::pair<std::string, py::handle>> {
using is_transparent = void;
inline Py_ALWAYS_INLINE bool operator()(const std::pair<std::string, py::handle>& lhs,
const std::pair<std::string, py::handle>& rhs) const {
inline constexpr Py_ALWAYS_INLINE bool operator()(const std::pair<std::string, py::handle>& lhs,
const std::pair<std::string, py::handle>& rhs)
const noexcept(noexcept(std::equal_to<std::string>{}(lhs.first, rhs.first))) {
return std::equal_to<std::string>{}(lhs.first, rhs.first) &&
std::equal_to<py::handle>{}(lhs.second, rhs.second);
}
};
template <>
struct std::not_equal_to<std::pair<std::string, py::handle>> {
using is_transparent = void;
inline Py_ALWAYS_INLINE bool operator()(const std::pair<std::string, py::handle>& lhs,
const std::pair<std::string, py::handle>& rhs) const {
inline constexpr Py_ALWAYS_INLINE bool operator()(const std::pair<std::string, py::handle>& lhs,
const std::pair<std::string, py::handle>& rhs)
const noexcept(noexcept(std::not_equal_to<std::string>{}(lhs.first, rhs.first))) {
return std::not_equal_to<std::string>{}(lhs.first, rhs.first) ||
std::not_equal_to<py::handle>{}(lhs.second, rhs.second);
}
};
template <class T, class U>
struct std::hash<std::pair<T, U>> {
using is_transparent = void;
inline Py_ALWAYS_INLINE std::size_t operator()(const std::pair<T, U>& p) const {
inline constexpr Py_ALWAYS_INLINE std::size_t operator()(const std::pair<T, U>& p) const
noexcept(noexcept(std::hash<T>{}(p.first)) && noexcept(std::hash<U>{}(p.second))) {
std::size_t seed = 0;
HashCombine(seed, p.first);
HashCombine(seed, p.second);
Expand Down
4 changes: 2 additions & 2 deletions include/mutex.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ limitations under the License.

class pymutex {
public:
pymutex() = default;
~pymutex() = default;
pymutex() noexcept = default;
~pymutex() noexcept = default;

pymutex(const pymutex &) = delete;
pymutex &operator=(const pymutex &) = delete;
Expand Down
2 changes: 1 addition & 1 deletion include/pymacros.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ namespace py = pybind11;
#define Py_IsFalse(x) Py_Is((x), Py_False)
#endif

inline Py_ALWAYS_INLINE bool Py_IsConstant(PyObject* x) {
inline constexpr Py_ALWAYS_INLINE bool Py_IsConstant(PyObject* x) noexcept {
return Py_IsNone(x) || Py_IsTrue(x) || Py_IsFalse(x);
}
#define Py_IsConstant(x) Py_IsConstant(x)
Expand Down
4 changes: 3 additions & 1 deletion include/stdutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ limitations under the License.
#include <cstddef> // std::size_t
#include <vector> // std::vector

#include "include/pymacros.h" // Py_ALWAYS_INLINE

template <typename T>
inline std::vector<T> reserved_vector(std::size_t size) {
inline Py_ALWAYS_INLINE std::vector<T> reserved_vector(std::size_t size) {
std::vector<T> v{};
v.reserve(size);
return v;
Expand Down
3 changes: 2 additions & 1 deletion include/treespec.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ class PyTreeSpec {
}

[[nodiscard]] inline Py_ALWAYS_INLINE ssize_t GetNumNodes() const {
EXPECT_FALSE(m_traversal.empty(), "The tree node traversal is empty.");
return py::ssize_t_cast(m_traversal.size());
}

Expand Down Expand Up @@ -417,7 +418,7 @@ class PyTreeIter {
PyTreeIter(PyTreeIter &&) = delete;
PyTreeIter &operator=(PyTreeIter &&) = delete;

[[nodiscard]] PyTreeIter &Iter() { return *this; }
[[nodiscard]] PyTreeIter &Iter() noexcept { return *this; }

[[nodiscard]] py::object Next();

Expand Down
3 changes: 1 addition & 2 deletions src/treespec/treespec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -568,8 +568,8 @@ ssize_t PyTreeSpec::PathsImpl(Span& paths, // NOLINT[misc-no-recursion]
}

std::vector<py::tuple> PyTreeSpec::Paths() const {
auto paths = std::vector<py::tuple>{};
const ssize_t num_leaves = GetNumLeaves();
auto paths = reserved_vector<py::tuple>(num_leaves);
if (num_leaves == 0) [[unlikely]] {
return paths;
}
Expand All @@ -578,7 +578,6 @@ std::vector<py::tuple> PyTreeSpec::Paths() const {
paths.emplace_back();
return paths;
}
paths.reserve(num_leaves);
auto stack = reserved_vector<py::handle>(4);
const ssize_t num_nodes_walked = PathsImpl(paths, stack, num_nodes - 1, 0);
std::reverse(paths.begin(), paths.end());
Expand Down

0 comments on commit 2361e5f

Please sign in to comment.