Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add nodiscard attribute #31

Merged
merged 1 commit into from
Dec 14, 2021
Merged
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 CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
if(MSVC)
add_compile_options(/permissive- /W4)
else()
add_compile_options(-Wall -Wextra -Wpedantic)
add_compile_options(-Wall -Wextra -Wpedantic -Wno-c++17-extensions)
endif()

find_package(Threads REQUIRED)
Expand Down
24 changes: 17 additions & 7 deletions include/rigtorp/SPSCQueue.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@ SOFTWARE.
#include <stdexcept>
#include <type_traits> // std::enable_if, std::is_*_constructible

#ifdef __has_cpp_attribute
#if __has_cpp_attribute(nodiscard)
#define RIGTORP_NODISCARD [[nodiscard]]
#endif
#endif
#ifndef RIGTORP_NODISCARD
#define RIGTORP_NODISCARD
#endif

namespace rigtorp {

template <typename T, typename Allocator = std::allocator<T>> class SPSCQueue {
Expand Down Expand Up @@ -110,7 +119,7 @@ template <typename T, typename Allocator = std::allocator<T>> class SPSCQueue {
}

template <typename... Args>
bool try_emplace(Args &&...args) noexcept(
RIGTORP_NODISCARD bool try_emplace(Args &&...args) noexcept(
std::is_nothrow_constructible<T, Args &&...>::value) {
static_assert(std::is_constructible<T, Args &&...>::value,
"T must be constructible with Args&&...");
Expand Down Expand Up @@ -142,7 +151,7 @@ template <typename T, typename Allocator = std::allocator<T>> class SPSCQueue {
emplace(std::forward<P>(v));
}

bool
RIGTORP_NODISCARD bool
try_push(const T &v) noexcept(std::is_nothrow_copy_constructible<T>::value) {
static_assert(std::is_copy_constructible<T>::value,
"T must be copy constructible");
Expand All @@ -151,11 +160,12 @@ template <typename T, typename Allocator = std::allocator<T>> class SPSCQueue {

template <typename P, typename = typename std::enable_if<
std::is_constructible<T, P &&>::value>::type>
bool try_push(P &&v) noexcept(std::is_nothrow_constructible<T, P &&>::value) {
RIGTORP_NODISCARD bool
try_push(P &&v) noexcept(std::is_nothrow_constructible<T, P &&>::value) {
return try_emplace(std::forward<P>(v));
}

T *front() noexcept {
RIGTORP_NODISCARD T *front() noexcept {
auto const readIdx = readIdx_.load(std::memory_order_relaxed);
if (readIdx == writeIdxCache_) {
writeIdxCache_ = writeIdx_.load(std::memory_order_acquire);
Expand All @@ -179,7 +189,7 @@ template <typename T, typename Allocator = std::allocator<T>> class SPSCQueue {
readIdx_.store(nextReadIdx, std::memory_order_release);
}

size_t size() const noexcept {
RIGTORP_NODISCARD size_t size() const noexcept {
std::ptrdiff_t diff = writeIdx_.load(std::memory_order_acquire) -
readIdx_.load(std::memory_order_acquire);
if (diff < 0) {
Expand All @@ -188,12 +198,12 @@ template <typename T, typename Allocator = std::allocator<T>> class SPSCQueue {
return static_cast<size_t>(diff);
}

bool empty() const noexcept {
RIGTORP_NODISCARD bool empty() const noexcept {
return writeIdx_.load(std::memory_order_acquire) ==
readIdx_.load(std::memory_order_acquire);
}

size_t capacity() const noexcept { return capacity_ - 1; }
RIGTORP_NODISCARD size_t capacity() const noexcept { return capacity_ - 1; }

private:
#ifdef __cpp_lib_hardware_interference_size
Expand Down
16 changes: 8 additions & 8 deletions src/SPSCQueueTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,16 +104,16 @@ int main(int argc, char *argv[]) {
// lvalue
Test v;
q.emplace(v);
q.try_emplace(v);
(void)q.try_emplace(v);
q.push(v);
q.try_push(v);
(void)q.try_push(v);
static_assert(noexcept(q.emplace(v)) == false, "");
static_assert(noexcept(q.try_emplace(v)) == false, "");
static_assert(noexcept(q.push(v)) == false, "");
static_assert(noexcept(q.try_push(v)) == false, "");
// xvalue
q.push(Test());
q.try_push(Test());
(void)q.try_push(Test());
static_assert(noexcept(q.push(Test())) == false, "");
static_assert(noexcept(q.try_push(Test())) == false, "");
}
Expand All @@ -129,16 +129,16 @@ int main(int argc, char *argv[]) {
// lvalue
Test v;
q.emplace(v);
q.try_emplace(v);
(void)q.try_emplace(v);
q.push(v);
q.try_push(v);
(void)q.try_push(v);
static_assert(noexcept(q.emplace(v)) == true, "");
static_assert(noexcept(q.try_emplace(v)) == true, "");
static_assert(noexcept(q.push(v)) == true, "");
static_assert(noexcept(q.try_push(v)) == true, "");
// xvalue
q.push(Test());
q.try_push(Test());
(void)q.try_push(Test());
static_assert(noexcept(q.push(Test())) == true, "");
static_assert(noexcept(q.try_push(Test())) == true, "");
}
Expand All @@ -154,9 +154,9 @@ int main(int argc, char *argv[]) {
// q.try_push(v);
// xvalue
q.emplace(std::unique_ptr<int>(new int(1)));
q.try_emplace(std::unique_ptr<int>(new int(1)));
(void)q.try_emplace(std::unique_ptr<int>(new int(1)));
q.push(std::unique_ptr<int>(new int(1)));
q.try_push(std::unique_ptr<int>(new int(1)));
(void)q.try_push(std::unique_ptr<int>(new int(1)));
auto v = std::unique_ptr<int>(new int(1));
static_assert(noexcept(q.emplace(std::move(v))) == true, "");
static_assert(noexcept(q.try_emplace(std::move(v))) == true, "");
Expand Down