Skip to content
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
9 changes: 4 additions & 5 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
---
Language: Cpp
# BasedOnStyle: LLVM
Language: Cpp
Standard: c++20
TabWidth: 2
UseTab: Never
AccessModifierOffset: -2
AlignAfterOpenBracket: true
AlignConsecutiveAssignments: false
Expand Down Expand Up @@ -61,8 +63,5 @@ SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
TabWidth: 2
UseTab: Never
...

2 changes: 1 addition & 1 deletion .clang-tidy
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
Checks: '-*,clang-analyzer-*,cppcoreguidelines-*,performance-*,portability-*,readability-*,bugprone-*,modernize-*,-modernize-use-trailing-return-type,-modernize-pass-by-value'
Checks: '-*,clang-analyzer-*,cppcoreguidelines-*,performance-*,portability-*,readability-*,-readability-identifier-length,bugprone-*,modernize-*,-modernize-use-trailing-return-type,misc-*'
FormatStyle: file
CheckOptions:
- key: readability-braces-around-statements.ShortStatementLines
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-sanitizers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
- uses: actions/checkout@v2

- name: Configure cmake
run: CC=clang-12 CXX=clang++-12 cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -D${{matrix.sanitizer}}=ON -DEVERY_WARNING=ON
run: CC=clang CXX=clang++ cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -D${{matrix.sanitizer}}=ON -DEVERY_WARNING=ON

- name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --verbose
Expand Down
30 changes: 28 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,38 @@ jobs:
strategy:
matrix:
os: [windows-latest, macos-latest, ubuntu-latest]
compiler: [default, gcc, clang]

# Only run "default" on Windows and macOS, but both Clang and GCC on Linux.
exclude:
- os: windows-latest
compiler: gcc
- os: windows-latest
compiler: clang
- os: macos-latest
compiler: gcc
- os: macos-latest
compiler: clang
- os: ubuntu-latest
compiler: default

steps:
- uses: actions/checkout@v2

- name: Configure cmake
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
- name: Configure CMake (Linux – GCC)
if: matrix.os == 'ubuntu-latest' && matrix.compiler == 'gcc'
run: |
cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++

- name: Configure CMake (Linux – Clang)
if: matrix.os == 'ubuntu-latest' && matrix.compiler == 'clang'
run: |
cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++

- name: Configure CMake (Windows / macOS – default)
if: matrix.compiler == 'default'
run: |
cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }}

- name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --verbose
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.0)
cmake_minimum_required(VERSION 3.20)
project(sigs)

set(CMAKE_COLOR_MAKEFILE ON)
Expand Down
23 changes: 12 additions & 11 deletions cmake/compilation.cmake
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

set(COMMON_COMPILER_WARNINGS "-Wno-unused-parameter -Wempty-body -Woverloaded-virtual -Wtautological-compare -Wshadow -Wmissing-noreturn -Wdouble-promotion")
Expand Down Expand Up @@ -37,15 +37,15 @@ endif()

if (NOT MSVC)
# Clang/GCC
set(REL_OPTS "-pipe -fno-exceptions -fvisibility=hidden -fvisibility-inlines-hidden -ffast-math -funroll-loops")
set(REL_OPTS "-O3 -pipe -fno-exceptions -fvisibility=hidden -fvisibility-inlines-hidden -ffast-math -funroll-loops")

# GCC only
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
set(REL_OPTS "${REL_OPTS} -fno-implement-inlines")

# Clang only
elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
set(REL_OPTS "${REL_OPTS} -Ofast")
set(REL_OPTS "${REL_OPTS}")

if (EVERY_WARNING)
# But ignore some warnings.
Expand All @@ -61,7 +61,7 @@ if (NOT MSVC)
endif()

if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
set(target_version "7.1")
set(target_version "12.0")
if (NOT (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER ${target_version} OR
CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL ${target_version}))
message(FATAL_ERROR "Requires GCC >= ${target_version}.")
Expand All @@ -75,11 +75,12 @@ if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC10_WARNINGS}")
endif()
elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
# Xcode 10 was based on Clang 6 which has full C++17 support.
# Xcode 15 was based on Clang 15 which has full C++20 support (previously the Xcode version was
# ahead of the Clang version).
if (APPLE AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "AppleClang")
set(target_version "10.0")
set(target_version "15.0")
else()
set(target_version "6")
set(target_version "15")
endif()

if (NOT (CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL ${target_version} OR
Expand All @@ -90,11 +91,11 @@ elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CLANG_WARNINGS} ${CLANG_ERRORS}")
elseif (MSVC AND (${MSVC_VERSION} GREATER_EQUAL 1910))
# Requires at least VS2017 (v1910).
# C++17 support is implicitly enabled.
elseif (MSVC AND (${MSVC_VERSION} GREATER_EQUAL 1929))
# Requires at least VS2019 (v1929).
# C++20 support is implicitly enabled.
else()
message(FATAL_ERROR "Your compiler does not support C++17 - aborting!")
message(FATAL_ERROR "Your compiler does not support C++20 - aborting!")
endif()

# Detect if ccache is installed and use if it is the case.
Expand Down
66 changes: 41 additions & 25 deletions sigs.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <cassert>
#include <cstddef>
#include <functional>
#include <initializer_list>
#include <memory>
#include <mutex>
#include <optional>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>
Expand All @@ -44,20 +42,16 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
namespace sigs {

template <std::size_t... Ns>
class Seq {
};
class Seq {};

template <std::size_t N, std::size_t... Ns>
class MakeSeq : public MakeSeq<N - 1, N - 1, Ns...> {
};
class MakeSeq : public MakeSeq<N - 1, N - 1, Ns...> {};

template <std::size_t... Ns>
class MakeSeq<0, Ns...> : public Seq<Ns...> {
};
class MakeSeq<0, Ns...> : public Seq<Ns...> {};

template <std::size_t>
class Placeholder {
};
class Placeholder {};

} // namespace sigs

Expand All @@ -66,8 +60,7 @@ class Placeholder {
namespace std {

template <size_t N>
class is_placeholder<sigs::Placeholder<N>> : public integral_constant<std::size_t, N + 1> {
};
class is_placeholder<sigs::Placeholder<N>> : public integral_constant<std::size_t, N + 1> {};

} // namespace std

Expand All @@ -79,8 +72,14 @@ namespace sigs {
*/
template <typename... Args>
struct Use final {
Use(const Use &) = delete;
Use(Use &&) = delete;

Use &operator=(const Use &) = delete;
Use &operator=(Use &&) = delete;

template <typename Cls, typename Ret>
[[nodiscard]] static inline auto overloadOf(Ret (Cls::*MembFunc)(Args...)) noexcept
[[nodiscard]] static auto overloadOf(Ret (Cls::*MembFunc)(Args...)) noexcept
{
return MembFunc;
}
Expand All @@ -91,6 +90,15 @@ class ConnectionBase final {
friend class BasicSignal;

public:
ConnectionBase() noexcept = default;
~ConnectionBase() noexcept = default;

ConnectionBase(const ConnectionBase &) noexcept = default;
ConnectionBase(ConnectionBase &&) noexcept = default;

ConnectionBase &operator=(const ConnectionBase &) noexcept = default;
ConnectionBase &operator=(ConnectionBase &&) noexcept = default;

void disconnect()
{
if (deleter) deleter();
Expand Down Expand Up @@ -257,33 +265,41 @@ class BasicSignal<Ret(Args...), Lock> {
{
}

inline Connection connect(const Slot &slot) noexcept
~Interface() noexcept = default;

Interface(const Interface &) = delete;
Interface(Interface &&) = delete;

Interface &operator=(const Interface &) = delete;
Interface &operator=(Interface &&) = delete;

Connection connect(const Slot &slot) noexcept
{
return sig_->connect(slot);
}

inline Connection connect(Slot &&slot) noexcept
Connection connect(Slot &&slot) noexcept
{
return sig_->connect(slot);
return sig_->connect(std::move(slot));
}

template <typename Instance, typename MembFunc>
inline Connection connect(Instance *instance, MembFunc Instance::*mf) noexcept
Connection connect(Instance *instance, MembFunc Instance::*mf) noexcept
{
return sig_->connect(instance, mf);
}

inline Connection connect(BasicSignal &signal) noexcept
Connection connect(BasicSignal &signal) noexcept
{
return sig_->connect(signal);
}

inline void disconnect(std::optional<Connection> conn) noexcept
void disconnect(std::optional<Connection> conn) noexcept
{
sig_->disconnect(conn);
}

inline void disconnect(BasicSignal &signal) noexcept
void disconnect(BasicSignal &signal) noexcept
{
sig_->disconnect(signal);
}
Expand Down Expand Up @@ -432,7 +448,7 @@ class BasicSignal<Ret(Args...), Lock> {
}
}

[[nodiscard]] inline std::unique_ptr<Interface> interface() noexcept
[[nodiscard]] std::unique_ptr<Interface> interface() noexcept
{
return std::make_unique<Interface>(this);
}
Expand All @@ -451,7 +467,7 @@ class BasicSignal<Ret(Args...), Lock> {
}

private:
[[nodiscard]] inline Connection makeConnection() noexcept
[[nodiscard]] Connection makeConnection() noexcept
{
auto conn = std::make_shared<ConnectionBase>();
conn->deleter = [this, conn] { this->disconnect(conn); };
Expand Down Expand Up @@ -483,14 +499,14 @@ class BasicSignal<Ret(Args...), Lock> {
}

template <typename Instance, typename MembFunc, std::size_t... Ns>
[[nodiscard]] inline Slot bindMf(Instance *instance, MembFunc Instance::*mf,
[[nodiscard]] Slot bindMf(Instance *instance, MembFunc Instance::*mf,
Seq<Ns...> /*unused*/) noexcept
{
return std::bind(mf, instance, Placeholder<Ns>()...);
}

template <typename Instance, typename MembFunc>
[[nodiscard]] inline Slot bindMf(Instance *instance, MembFunc Instance::*mf) noexcept
[[nodiscard]] Slot bindMf(Instance *instance, MembFunc Instance::*mf) noexcept
{
return bindMf(instance, mf, MakeSeq<sizeof...(Args)>());
}
Expand All @@ -500,7 +516,7 @@ class BasicSignal<Ret(Args...), Lock> {
std::atomic_bool blocked_ = false;
};

using BasicLock = std::lock_guard<std::mutex>;
using BasicLock = std::scoped_lock<std::mutex>;

/// Default signal types.
//@{
Expand Down
Loading