Added comparison operators and tests for them

This commit is contained in:
Antony Polukhin 2016-10-12 20:22:24 +03:00
parent 46860b50a9
commit b75dfd361c
8 changed files with 149 additions and 0 deletions

View File

@ -119,9 +119,27 @@ public:
return !size();
}
/// @brief Allows to check that capturing stack trace was successful.
/// @returns `true` if `this->size() != 0`
///
/// @b Complexity: O(1)
BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
/// @brief Compares stacktraces for less, order is platform dependant.
///
/// @b Complexity: Amortized O(1); worst case O(size())
BOOST_STACKTRACE_FUNCTION bool operator< (const stacktrace& rhs) const BOOST_NOEXCEPT;
/// @brief Compares stacktraces for equality.
///
/// @b Complexity: Amortized O(1); worst case O(size())
BOOST_STACKTRACE_FUNCTION bool operator==(const stacktrace& rhs) const BOOST_NOEXCEPT;
};
inline bool operator> (const stacktrace& lhs, const stacktrace& rhs) BOOST_NOEXCEPT { return rhs < lhs; }
inline bool operator<=(const stacktrace& lhs, const stacktrace& rhs) BOOST_NOEXCEPT { return !(lhs > rhs); }
inline bool operator>=(const stacktrace& lhs, const stacktrace& rhs) BOOST_NOEXCEPT { return !(lhs < rhs); }
inline bool operator!=(const stacktrace& lhs, const stacktrace& rhs) BOOST_NOEXCEPT { return !(lhs == rhs); }
/// Outputs stacktrace in a human readable format to output stream.
template <class CharT, class TraitsT>

View File

@ -76,6 +76,32 @@ struct backtrace_holder {
return res;
}
inline bool operator< (const backtrace_holder& rhs) const BOOST_NOEXCEPT {
if (frames_count != rhs.frames_count) {
return frames_count < rhs.frames_count;
} else if (frames.get() == rhs.frames.get()) {
return false;
}
return std::lexicographical_compare(
frames.get(), frames.get() + frames_count,
rhs.frames.get(), rhs.frames.get() + rhs.frames_count
);
}
inline bool operator==(const backtrace_holder& rhs) const BOOST_NOEXCEPT {
if (frames_count != rhs.frames_count) {
return false;
} else if (frames.get() == rhs.frames.get()) {
return true;
}
return std::equal(
frames.get(), frames.get() + frames_count,
rhs.frames.get()
);
}
};
}}} // namespace boost::stacktrace::detail

View File

@ -50,6 +50,32 @@ struct backtrace_holder {
return res;
}
inline bool operator< (const backtrace_holder& rhs) const BOOST_NOEXCEPT {
if (frames_count != rhs.frames_count) {
return frames_count < rhs.frames_count;
} else if (this == &rhs) {
return false;
}
return std::lexicographical_compare(
buffer, buffer + frames_count,
rhs.buffer, rhs.buffer + rhs.frames_count
);
}
inline bool operator==(const backtrace_holder& rhs) const BOOST_NOEXCEPT {
if (frames_count != rhs.frames_count) {
return false;
} else if (this == &rhs) {
return true;
}
return std::equal(
buffer, buffer + frames_count,
rhs.buffer
);
}
};
}}} // namespace boost::stacktrace::detail

View File

@ -23,6 +23,14 @@ struct backtrace_holder {
inline std::string get_frame(std::size_t /*frame*/) const {
return std::string();
}
inline bool operator< (const backtrace_holder& rhs) const BOOST_NOEXCEPT {
return false;
}
inline bool operator==(const backtrace_holder& rhs) const BOOST_NOEXCEPT {
return true;
}
};
}}} // namespace boost::stacktrace::detail

View File

@ -79,6 +79,32 @@ struct backtrace_holder {
}
return res;
}
inline bool operator< (const backtrace_holder& rhs) const BOOST_NOEXCEPT {
if (frames_count != rhs.frames_count) {
return frames_count < rhs.frames_count;
} else if (this == &rhs) {
return false;
}
return std::lexicographical_compare(
buffer, buffer + frames_count,
rhs.buffer, rhs.buffer + rhs.frames_count
);
}
inline bool operator==(const backtrace_holder& rhs) const BOOST_NOEXCEPT {
if (frames_count != rhs.frames_count) {
return false;
} else if (this == &rhs) {
return true;
}
return std::equal(
buffer, buffer + frames_count,
rhs.buffer
);
}
};
}}} // namespace boost::stacktrace::detail

View File

@ -53,6 +53,13 @@ std::string stacktrace::operator[](std::size_t frame) const {
return impl_.get_frame(frame);
}
bool stacktrace::operator< (const stacktrace& rhs) const BOOST_NOEXCEPT {
return impl_ < rhs.impl_;
}
bool stacktrace::operator==(const stacktrace& rhs) const BOOST_NOEXCEPT {
return impl_ == rhs.impl_;
}
}}

View File

@ -67,6 +67,13 @@ std::string stacktrace::operator[](std::size_t frame) const {
return boost::stacktrace::detail::to_bt(impl_).get_frame(frame);
}
bool stacktrace::operator< (const stacktrace& rhs) const BOOST_NOEXCEPT {
return boost::stacktrace::detail::to_bt(impl_) < boost::stacktrace::detail::to_bt(rhs.impl_);
}
bool stacktrace::operator==(const stacktrace& rhs) const BOOST_NOEXCEPT {
return boost::stacktrace::detail::to_bt(impl_) == boost::stacktrace::detail::to_bt(rhs.impl_);
}
}}

View File

@ -32,6 +32,8 @@ void test_deeply_nested_namespaces() {
#if defined(BOOST_STACKTRACE_DYN_LINK) || !defined(BOOST_STACKTRACE_USE_BACKTRACE)
BOOST_TEST(ss.str().find("get_backtrace_from_nested_namespaces") != std::string::npos);
#endif
// TODO: BOOST_TEST(return_from_nested_namespaces() != return_from_nested_namespaces());
}
void test_nested() {
@ -61,10 +63,39 @@ void test_nested() {
#endif
}
void test_comparisons() {
stacktrace nst = return_from_nested_namespaces();
stacktrace st;
stacktrace cst(st);
BOOST_TEST(nst);
BOOST_TEST(st);
BOOST_TEST(nst != st);
BOOST_TEST(st != nst);
BOOST_TEST(st == st);
BOOST_TEST(nst == nst);
BOOST_TEST(nst != cst);
BOOST_TEST(cst != nst);
BOOST_TEST(cst == st);
BOOST_TEST(cst == cst);
BOOST_TEST(nst < st || nst > st);
BOOST_TEST(st < nst || nst < st);
BOOST_TEST(st <= st);
BOOST_TEST(nst <= nst);
BOOST_TEST(st >= st);
BOOST_TEST(nst >= nst);
BOOST_TEST(nst < cst || cst < nst);
BOOST_TEST(nst > cst || cst > nst);
}
int main() {
test_deeply_nested_namespaces();
test_nested();
test_comparisons();
return boost::report_errors();
}