├── .gitignore ├── .gitmodules ├── .travis.yml ├── CMakeLists.txt ├── LICENSE ├── README.md ├── appveyor.yml ├── benchmarks └── github_wiki.md ├── etc └── valgrind.sup ├── examples ├── common │ ├── Logger.cpp │ ├── Logger.hpp │ └── Signals.hpp └── observable_dictionary │ ├── CollectionOp.hpp │ ├── IObservableDictionary.hpp │ ├── ObservableDictionaryExample.cpp │ └── SortedObservableDictionary.hpp ├── include └── wigwag │ ├── api_version.hpp │ ├── detail │ ├── annotations.hpp │ ├── async_handler.hpp │ ├── at_scope_exit.hpp │ ├── config.hpp │ ├── coverage.hpp │ ├── creation_storage_adapter.hpp │ ├── disable_warnings.hpp │ ├── enable_warnings.hpp │ ├── enabler.hpp │ ├── flags.hpp │ ├── intrusive_list.hpp │ ├── intrusive_ptr.hpp │ ├── intrusive_ref_counter.hpp │ ├── iterator_base.hpp │ ├── listenable_impl.hpp │ ├── policies │ │ ├── creation │ │ │ └── policy_concept.hpp │ │ ├── exception_handling │ │ │ └── policy_concept.hpp │ │ ├── life_assurance │ │ │ └── policy_concept.hpp │ │ ├── ref_counter │ │ │ └── policy_concept.hpp │ │ ├── state_populating │ │ │ └── policy_concept.hpp │ │ └── threading │ │ │ └── policy_concept.hpp │ ├── policies_concepts.hpp │ ├── policy_picker.hpp │ ├── policy_version_detector.hpp │ ├── signal_connector_impl.hpp │ ├── signal_impl.hpp │ ├── stdcpp_annotations.hpp │ ├── storage_for.hpp │ └── type_expression_check.hpp │ ├── handler_attributes.hpp │ ├── life_token.hpp │ ├── listenable.hpp │ ├── policies.hpp │ ├── policies │ ├── creation │ │ ├── ahead_of_time.hpp │ │ ├── lazy.hpp │ │ ├── policies.hpp │ │ └── tag.hpp │ ├── exception_handling │ │ ├── none.hpp │ │ ├── policies.hpp │ │ ├── print_to_stderr.hpp │ │ └── tag.hpp │ ├── life_assurance │ │ ├── intrusive_life_tokens.hpp │ │ ├── none.hpp │ │ ├── policies.hpp │ │ ├── single_threaded.hpp │ │ └── tag.hpp │ ├── ref_counter │ │ ├── atomic.hpp │ │ ├── policies.hpp │ │ ├── single_threaded.hpp │ │ └── tag.hpp │ ├── state_populating │ │ ├── none.hpp │ │ ├── policies.hpp │ │ ├── populator_and_withdrawer.hpp │ │ ├── populator_only.hpp │ │ └── tag.hpp │ └── threading │ │ ├── none.hpp │ │ ├── own_mutex.hpp │ │ ├── own_recursive_mutex.hpp │ │ ├── policies.hpp │ │ ├── shared_mutex.hpp │ │ ├── shared_recursive_mutex.hpp │ │ └── tag.hpp │ ├── signal.hpp │ ├── signal_attributes.hpp │ ├── signal_connector.hpp │ ├── task_executor.hpp │ ├── thread_task_executor.hpp │ ├── threadless_task_executor.hpp │ ├── token.hpp │ └── token_pool.hpp └── src ├── benchmarks ├── FunctionBenchmarks.hpp ├── GenericBenchmarks.hpp ├── MutexBenchmarks.hpp ├── SignalBenchmarks.hpp ├── descriptors │ ├── function │ │ ├── boost.hpp │ │ └── std.hpp │ ├── generic │ │ ├── boost.hpp │ │ ├── std.hpp │ │ └── wigwag.hpp │ ├── mutex │ │ ├── boost.hpp │ │ └── std.hpp │ └── signal │ │ ├── boost.hpp │ │ ├── qt5.hpp │ │ ├── sigcpp.hpp │ │ └── wigwag.hpp └── main.cpp └── test ├── api_v1_test.hpp ├── compilation_test.hpp ├── no_exceptions_compilation_test.cpp ├── pedantic_compilation_test.cpp └── utils ├── mutexed.hpp ├── profiler.hpp └── thread.hpp /.gitignore: -------------------------------------------------------------------------------- 1 | *.swo 2 | *.swp 3 | /*.taghl 4 | /.buildSettings 5 | /.clang_complete 6 | /.ninja_deps 7 | /.ninja_log 8 | /.vimrc 9 | /.ycm_extra_conf.py 10 | /.ycm_extra_conf.pyc 11 | /CMakeCache.txt 12 | /CMakeFiles 13 | /Makefile 14 | /bin 15 | /build 16 | /build.ninja 17 | /cmake_install.cmake 18 | /compile_commands.json 19 | /rules.ninja 20 | /tags 21 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "src/benchmarks/core"] 2 | path = src/benchmarks/core 3 | url = https://github.com/koplyarov/benchmarks.git 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: required 2 | dist: trusty 3 | language: cpp 4 | cache: apt 5 | 6 | matrix: 7 | include: 8 | - compiler: gcc 9 | addons: 10 | apt: 11 | sources: ['ubuntu-toolchain-r-test'] 12 | packages: ['g++-4.8', 'valgrind'] 13 | env: COMPILER=gcc-4.8 COMPILERXX=g++-4.8 14 | - compiler: clang 15 | addons: 16 | apt: 17 | packages: ['clang-3.5', 'valgrind'] 18 | env: COMPILER=clang-3.5 COMPILERXX=clang++-3.5 19 | 20 | before_install: 21 | - sudo apt-get install -yq cxxtest 22 | 23 | install: 24 | - wget http://ftp.de.debian.org/debian/pool/main/l/lcov/lcov_1.11.orig.tar.gz 25 | - tar xf lcov_1.11.orig.tar.gz 26 | - sudo make -C lcov-1.11/ install 27 | - gem install coveralls-lcov 28 | - if [ "$CXX" = "g++" ]; then sudo update-alternatives --install /usr/bin/gcov gcov /usr/bin/gcov-4.8 90; fi 29 | 30 | script: 31 | - ( mkdir build && cd build && CC="$COMPILER" CXX="$COMPILERXX" cmake -DWIGWAG_VALGRIND=TRUE .. && make ) 32 | - valgrind --suppressions=etc/valgrind.sup --tool=helgrind --gen-suppressions=all --error-exitcode=1 ./build/bin/wigwag_test 33 | - valgrind --suppressions=etc/valgrind.sup --tool=memcheck --leak-check=full --gen-suppressions=all --error-exitcode=1 ./build/bin/wigwag_test 34 | - rm -rf ./build 35 | - ( mkdir build && cd build && CC="$COMPILER" CXX="$COMPILERXX" cmake -DWIGWAG_COVERAGE=TRUE .. && make ) 36 | - ./build/bin/wigwag_test 37 | 38 | after_success: 39 | - if [ "$CXX" = "g++" ]; then echo "Sending coverage info"; lcov --directory . --capture --output-file coverage.info && lcov --remove coverage.info 'build/unittest_wigwag.cpp' 'src/*' '/usr/*' --output-file coverage.info && lcov --list coverage.info && coveralls-lcov --repo-token ${COVERALLS_TOKEN} coverage.info; fi 40 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(wigwag) 2 | cmake_minimum_required(VERSION 2.8.12) 3 | 4 | set(CMAKE_EXPORT_COMPILE_COMMANDS ON) 5 | 6 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") 7 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") 8 | 9 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) 10 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src) 11 | 12 | if (WIGWAG_VALGRIND) 13 | message(STATUS "Using valgrind annotations") 14 | add_definitions(-DWIGWAG_USE_HELGRIND_ANNOTATIONS=1) 15 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -include wigwag/detail/stdcpp_annotations.hpp") 16 | endif() 17 | 18 | if (MSVC) 19 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc") 20 | else() 21 | add_definitions(-Wall) 22 | add_definitions(-std=c++11) 23 | endif() 24 | 25 | if (WIGWAG_COVERAGE) 26 | message(STATUS "Using gcov for API_V1_test coverage analysis") 27 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0") 28 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage") 29 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -include wigwag/detail/coverage.hpp") 30 | endif() 31 | 32 | find_package(Threads) 33 | 34 | ###################################################################### 35 | 36 | if (MSVC) 37 | if ("${CMAKE_GENERATOR}" STREQUAL "Visual Studio 12 2013") 38 | set(UNCAUGHT_EXCEPTION_WORKAROUND "\"/D__uncaught_exception=[]{return false;}\"") 39 | else() 40 | set(UNCAUGHT_EXCEPTION_WORKAROUND "") 41 | endif() 42 | 43 | set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/src/test/no_exceptions_compilation_test.cpp PROPERTIES COMPILE_FLAGS 44 | "/W4 /WX /D_HAS_EXCEPTIONS=0 ${UNCAUGHT_EXCEPTION_WORKAROUND}") 45 | get_source_file_property(TMP_COMPILE_FLAGS ${CMAKE_CURRENT_SOURCE_DIR}/src/test/no_exceptions_compilation_test.cpp COMPILE_FLAGS) 46 | string(REPLACE "/EHsc" "/EHs-c-" TMP_COMPILE_FLAGS ${TMP_COMPILE_FLAGS}) 47 | set_source_files_properties(myprogram.cpp COMPILE_FLAGS ${TMP_COMPILE_FLAGS}) 48 | 49 | set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/src/test/pedantic_compilation_test.cpp PROPERTIES COMPILE_FLAGS 50 | "/W4 /WX") 51 | else() 52 | set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/src/test/no_exceptions_compilation_test.cpp PROPERTIES COMPILE_FLAGS 53 | "-Werror=all -Werror=extra -Werror=effc++ -Werror=pedantic -pedantic -pedantic-errors -fno-exceptions -fno-rtti") 54 | set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/src/test/pedantic_compilation_test.cpp PROPERTIES COMPILE_FLAGS 55 | "-Werror=all -Werror=extra -Werror=effc++ -Werror=pedantic -pedantic -pedantic-errors") 56 | endif() 57 | 58 | add_library(wigwag_pedantic_compilation_test 59 | ${CMAKE_CURRENT_SOURCE_DIR}/src/test/no_exceptions_compilation_test.cpp 60 | ${CMAKE_CURRENT_SOURCE_DIR}/src/test/pedantic_compilation_test.cpp) 61 | target_link_libraries(wigwag_pedantic_compilation_test) 62 | 63 | ###################################################################### 64 | 65 | add_library(example_common ${CMAKE_CURRENT_SOURCE_DIR}/examples/common/Logger.cpp) 66 | target_link_libraries(example_common ${CMAKE_THREAD_LIBS_INIT}) 67 | 68 | add_executable(example_observable_dictionary ${CMAKE_CURRENT_SOURCE_DIR}/examples/observable_dictionary/ObservableDictionaryExample.cpp) 69 | target_link_libraries(example_observable_dictionary example_common) 70 | 71 | ###################################################################### 72 | 73 | find_package(CxxTest) 74 | if(CXXTEST_FOUND) 75 | message(STATUS "Found cxxtest, enabling wigwag_test") 76 | include_directories(${CXXTEST_INCLUDE_DIR}) 77 | enable_testing() 78 | 79 | CXXTEST_ADD_TEST(wigwag_test unittest_wigwag.cpp 80 | ${CMAKE_CURRENT_SOURCE_DIR}/src/test/api_v1_test.hpp) 81 | 82 | if (MSVC) 83 | set_source_files_properties(unittest_wigwag.cpp PROPERTIES COMPILE_FLAGS "/wd4800") 84 | endif() 85 | 86 | target_link_libraries(wigwag_test ${CMAKE_THREAD_LIBS_INIT}) 87 | endif() 88 | 89 | ###################################################################### 90 | 91 | find_package(Boost COMPONENTS 92 | program_options 93 | system 94 | exception 95 | thread 96 | date_time 97 | regex 98 | serialization 99 | ) 100 | 101 | if (Boost_FOUND) 102 | message(STATUS "Found boost, enabling wigwag_benchmarks") 103 | add_subdirectory(src/benchmarks/core) 104 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/benchmarks/core) 105 | include_directories(${Boost_INCLUDE_DIRS}) 106 | 107 | if (NOT WIN32) 108 | find_package(PkgConfig REQUIRED) 109 | pkg_check_modules(SIGCPP2 sigc++-2.0) 110 | else() 111 | find_path(SIGCPP2_INCLUDE_DIR NAMES "sigc++/sigc++.h") 112 | find_path(SIGCPP2_CONFIG_INCLUDE_DIR NAMES sigc++config.h) 113 | find_library(SIGCPP2_LIBRARY NAMES sigc-2.0 PATH_SUFFIXES "lib" "sigc++/.libs") 114 | 115 | set(SIGCPP2_LIBRARIES ${SIGCPP2_LIBRARY}) 116 | set(SIGCPP2_INCLUDE_DIRS ${SIGCPP2_INCLUDE_DIR} ${SIGCPP2_CONFIG_INCLUDE_DIR}) 117 | 118 | include(FindPackageHandleStandardArgs) 119 | find_package_handle_standard_args(SIGCPP2 "Could NOT find SIGC++, try to set the path to SIGC++ root folder in the system variable SIGC++" 120 | SIGCPP2_LIBRARIES 121 | SIGCPP2_INCLUDE_DIRS 122 | ) 123 | endif() 124 | 125 | if (SIGCPP2_FOUND) 126 | add_definitions(-DWIGWAG_BENCHMARKS_SIGCPP2=1) 127 | include_directories(${SIGCPP2_INCLUDE_DIRS}) 128 | endif() 129 | 130 | find_package(Qt5Core) 131 | if (Qt5Core_FOUND) 132 | set(CMAKE_INCLUDE_CURRENT_DIR ON) 133 | set(CMAKE_AUTOMOC ON) 134 | add_definitions(-DWIGWAG_BENCHMARKS_QT5=1) 135 | include_directories(${Qt5Core_INCLUDE_DIRS}) 136 | add_definitions(${Qt5Core_DEFINITIONS}) 137 | if (NOT MSVC) 138 | set(CMAKE_CXX_FLAGS "${Qt5Core_EXECUTABLE_COMPILE_FLAGS}") 139 | endif() 140 | endif() 141 | 142 | add_executable(wigwag_benchmarks 143 | ${CMAKE_CURRENT_SOURCE_DIR}/src/benchmarks/descriptors/signal/qt5.hpp 144 | ${CMAKE_CURRENT_SOURCE_DIR}/src/benchmarks/main.cpp) 145 | 146 | if (SIGCPP2_FOUND) 147 | target_link_libraries(wigwag_benchmarks ${SIGCPP2_LIBRARIES}) 148 | endif() 149 | if (Qt5Core_FOUND) 150 | target_link_libraries(wigwag_benchmarks ${Qt5Core_LIBRARIES}) 151 | endif() 152 | 153 | target_link_libraries(wigwag_benchmarks 154 | ${Boost_LIBRARIES} 155 | ${CMAKE_THREAD_LIBS_INIT} 156 | benchmarks 157 | ) 158 | 159 | if (WIN32) 160 | target_link_libraries(wigwag_benchmarks ole32 oleaut32) 161 | else() 162 | target_link_libraries(wigwag_benchmarks rt) 163 | endif() 164 | endif() 165 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016, Dmitry Koplyarov 2 | 3 | Permission to use, copy, modify, and/or distribute this software for any 4 | purpose with or without fee is hereby granted, provided that the above 5 | copyright notice and this permission notice appear in all copies. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # wigwag 2 | Wigwag is a C++ signals library. 3 | You can read more on the [project wiki](https://github.com/koplyarov/wigwag/wiki). 4 | 5 | [![Build Status](https://travis-ci.org/koplyarov/wigwag.svg?branch=master)](https://travis-ci.org/koplyarov/wigwag) 6 | [![Build status](https://ci.appveyor.com/api/projects/status/2ypn11aif5huc912/branch/master?svg=true)](https://ci.appveyor.com/project/koplyarov/wigwag) 7 | [![Coverage Status](https://coveralls.io/repos/github/koplyarov/wigwag/badge.svg?branch=master)](https://coveralls.io/github/koplyarov/wigwag?branch=master) 8 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | version: "1.0.{build}" 2 | os: Visual Studio 2015 3 | platform: 4 | - Win32 5 | 6 | environment: 7 | global: 8 | MSVC_DEFAULT_OPTIONS: ON 9 | matrix: 10 | - VS_VERSION: "Visual Studio 12 2013" 11 | - VS_VERSION: "Visual Studio 14 2015" 12 | 13 | configuration: 14 | - Debug 15 | - Release 16 | 17 | init: 18 | - cmd: cmake --version 19 | - cmd: msbuild /version 20 | 21 | install: 22 | - cmd: git clone --depth 1 --branch 4.4 https://github.com/CxxTest/cxxtest.git 23 | 24 | clone_folder: C:\projects\wigwag 25 | 26 | before_build: 27 | - cmd: cd C:\projects\wigwag 28 | - cmd: md build 29 | - cmd: cd build 30 | - cmd: if "%platform%"=="Win32" set CMAKE_GENERATOR_NAME=%VS_VERSION% 31 | - cmd: if "%platform%"=="x64" set CMAKE_GENERATOR_NAME=%VS_VERSION% Win64 32 | - cmd: cmake -G "%CMAKE_GENERATOR_NAME%" -DCMAKE_BUILD_TYPE=%configuration% -DCXXTEST_INCLUDE_DIR=%APPVEYOR_BUILD_FOLDER%\cxxtest -DCXXTEST_PYTHON_TESTGEN_EXECUTABLE=%APPVEYOR_BUILD_FOLDER%\cxxtest\python\scripts\cxxtestgen .. 33 | 34 | build: 35 | project: C:\projects\wigwag\build\wigwag.sln 36 | parallel: true 37 | verbosity: minimal 38 | 39 | test_script: 40 | - cmd: "%APPVEYOR_BUILD_FOLDER%\\build\\bin\\%CONFIGURATION%\\wigwag_test" 41 | -------------------------------------------------------------------------------- /etc/valgrind.sup: -------------------------------------------------------------------------------- 1 | { 2 | 3 | Helgrind:Race 4 | ... 5 | fun:_ZNSt10shared_ptrINSt6thread10_Impl_baseEED1Ev 6 | ... 7 | } 8 | 9 | { 10 | 11 | Helgrind:Race 12 | ... 13 | fun:_ZNSt6atomicIbEaSEb 14 | ... 15 | } 16 | 17 | { 18 | 19 | Helgrind:Race 20 | ... 21 | fun:_ZNKSt11atomic_boolaSEb 22 | ... 23 | } 24 | 25 | { 26 | 27 | Helgrind:Race 28 | ... 29 | fun:_ZNSt11atomic_boolaSEb 30 | ... 31 | } 32 | 33 | { 34 | 35 | Helgrind:Race 36 | ... 37 | fun:_ZNKSt6atomicIbEcvbEv 38 | ... 39 | } 40 | 41 | { 42 | 43 | Helgrind:Race 44 | ... 45 | fun:_ZNKSt11atomic_boolcvbEv 46 | ... 47 | } 48 | 49 | { 50 | 51 | Memcheck:Leak 52 | fun:malloc 53 | ... 54 | fun:_dl_init 55 | ... 56 | } 57 | -------------------------------------------------------------------------------- /examples/common/Logger.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016, Dmitry Koplyarov 2 | // 3 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 4 | // provided that the above copyright notice and this permission notice appear in all copies. 5 | // 6 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 7 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 8 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 9 | 10 | 11 | #include "Logger.hpp" 12 | 13 | 14 | std::mutex Logger::s_mutex; 15 | 16 | void Logger::Write(LogLevel logLevel, std::string str) 17 | { 18 | std::lock_guard l(s_mutex); 19 | switch (logLevel) 20 | { 21 | case LogLevel::Info: 22 | std::cerr << "[Info] "; 23 | break; 24 | case LogLevel::Error: 25 | std::cerr << "[Error] "; 26 | break; 27 | default: 28 | std::cerr << "[LogLevel: " << static_cast::type>(logLevel) << "] "; 29 | break; 30 | } 31 | std::cerr << str << std::endl; 32 | } 33 | -------------------------------------------------------------------------------- /examples/common/Logger.hpp: -------------------------------------------------------------------------------- 1 | #ifndef EXAMPLES_COMMON_LOGGER_HPP 2 | #define EXAMPLES_COMMON_LOGGER_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | 19 | enum class LogLevel 20 | { 21 | Info, 22 | Error 23 | }; 24 | 25 | 26 | class Logger 27 | { 28 | public: 29 | class LoggerWriter 30 | { 31 | private: 32 | LogLevel _logLevel; 33 | std::stringstream _stream; 34 | bool _moved; 35 | 36 | public: 37 | LoggerWriter(LogLevel logLevel) 38 | : _logLevel(logLevel), _moved(false) 39 | { } 40 | 41 | LoggerWriter(LoggerWriter&& other) 42 | : _logLevel(other._logLevel), _moved(false) 43 | { 44 | _stream << other._stream.str(); 45 | other._moved = true; 46 | } 47 | 48 | ~LoggerWriter() 49 | { 50 | if (!_moved) 51 | Logger::Write(_logLevel, _stream.str()); 52 | } 53 | 54 | template < typename T_ > 55 | LoggerWriter& operator << (T_&& val) 56 | { 57 | _stream << val; 58 | return *this; 59 | } 60 | }; 61 | 62 | private: 63 | static std::mutex s_mutex; 64 | 65 | public: 66 | static LoggerWriter Log(LogLevel logLevel) 67 | { return LoggerWriter(logLevel); } 68 | 69 | private: 70 | static void Write(LogLevel logLevel, std::string str); 71 | }; 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /examples/common/Signals.hpp: -------------------------------------------------------------------------------- 1 | #ifndef EXAMPLES_COMMON_SIGNALS_HPP 2 | #define EXAMPLES_COMMON_SIGNALS_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | #include 16 | 17 | 18 | template < typename Signature_ > 19 | using SharedRMutexSignal = wigwag::signal< 20 | Signature_, 21 | wigwag::exception_handling::print_to_stderr, 22 | wigwag::threading::shared_recursive_mutex 23 | >; 24 | 25 | template < typename HandlerType_ > 26 | using SharedRMutexListenable = wigwag::listenable< 27 | HandlerType_, 28 | wigwag::exception_handling::print_to_stderr, 29 | wigwag::threading::shared_recursive_mutex 30 | >; 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /examples/observable_dictionary/CollectionOp.hpp: -------------------------------------------------------------------------------- 1 | #ifndef EXAMPLES_OBSERVABLE_DICTIONARY_COLLECTIONOP_HPP 2 | #define EXAMPLES_OBSERVABLE_DICTIONARY_COLLECTIONOP_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | enum class CollectionOp 15 | { 16 | ItemAdded, 17 | ItemRemoved 18 | }; 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /examples/observable_dictionary/IObservableDictionary.hpp: -------------------------------------------------------------------------------- 1 | #ifndef EXAMPLES_OBSERVABLE_DICTIONARY_IOBSERVABLEDICTIONARY_HPP 2 | #define EXAMPLES_OBSERVABLE_DICTIONARY_IOBSERVABLEDICTIONARY_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | #include 16 | 17 | #include "CollectionOp.hpp" 18 | 19 | 20 | template < typename Key_, typename Value_ > 21 | struct IObservableDictionaryListener 22 | { 23 | virtual ~IObservableDictionaryListener() { } 24 | 25 | virtual void OnItemAdded(const Key_&, const Value_&) = 0; 26 | virtual void OnItemRemoved(const Key_&, const Value_&) = 0; 27 | }; 28 | 29 | template < typename Key_, typename Value_ > 30 | using IObservableDictionaryListenerPtr = std::shared_ptr>; 31 | 32 | 33 | template < typename Key_, typename Value_ > 34 | struct IObservableDictionary 35 | { 36 | virtual ~IObservableDictionary() { } 37 | 38 | virtual std::recursive_mutex& SyncRoot() const = 0; 39 | 40 | virtual wigwag::signal_connector OnChanged() const = 0; 41 | virtual wigwag::token AddListener(const IObservableDictionaryListenerPtr& listener) const = 0; 42 | 43 | virtual int GetCount() const = 0; 44 | virtual bool IsEmpty() const = 0; 45 | 46 | virtual Value_ Get(const Key_& key) const = 0; 47 | virtual bool ContainsKey(const Key_& key) const = 0; 48 | virtual bool TryGet(const Key_& key, Value_& outValue) const = 0; 49 | 50 | virtual void Set(const Key_& key, const Value_& value) = 0; 51 | virtual void Remove(const Key_& key) = 0; 52 | virtual bool TryRemove(const Key_& key) = 0; 53 | 54 | virtual void Clear() = 0; 55 | }; 56 | 57 | 58 | template < typename Key_, typename Value_ > 59 | using IObservableDictionaryPtr = std::shared_ptr>; 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /examples/observable_dictionary/ObservableDictionaryExample.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016, Dmitry Koplyarov 2 | // 3 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 4 | // provided that the above copyright notice and this permission notice appear in all copies. 5 | // 6 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 7 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 8 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 9 | 10 | 11 | #include "../common/Logger.hpp" 12 | #include "SortedObservableDictionary.hpp" 13 | 14 | #include 15 | 16 | #include 17 | 18 | 19 | class DictListener : public virtual IObservableDictionaryListener 20 | { 21 | public: 22 | virtual void OnItemAdded(const int& k, const std::string& v) 23 | { 24 | Logger::Log(LogLevel::Info) << "DictListener::OnItemAdded(" << k << ", " << v << ")"; 25 | } 26 | 27 | virtual void OnItemRemoved(const int& k, const std::string& v) 28 | { 29 | Logger::Log(LogLevel::Info) << "DictListener::OnItemRemoved(" << k << ", " << v << ")"; 30 | } 31 | }; 32 | 33 | 34 | class Random 35 | { 36 | std::random_device _rd; 37 | std::mt19937 _mt; 38 | std::uniform_real_distribution _dist; 39 | 40 | public: 41 | Random() 42 | : _mt(_rd()), _dist(1.0, 10.0) 43 | { } 44 | 45 | std::string GenerateString(size_t size) 46 | { 47 | std::string s; 48 | for (size_t i = 0; i < size; ++i) 49 | s += 'a' + (int)_dist(_mt); 50 | return s; 51 | } 52 | }; 53 | 54 | 55 | int main() 56 | { 57 | using namespace std::this_thread; 58 | using namespace std::chrono; 59 | 60 | try 61 | { 62 | IObservableDictionaryPtr dict = std::make_shared>(); 63 | dict->Set(101, "qwe"); 64 | dict->Set(102, "asd"); 65 | 66 | wigwag::token_pool tp; 67 | tp += dict->AddListener(std::make_shared()); 68 | tp += dict->OnChanged().connect([](CollectionOp op, int k, const std::string& v) 69 | { 70 | std::string op_str; 71 | switch (op) 72 | { 73 | case CollectionOp::ItemAdded: 74 | op_str = "ItemAdded"; 75 | break; 76 | case CollectionOp::ItemRemoved: 77 | op_str = "ItemRemoved"; 78 | break; 79 | default: 80 | op_str = "Unknown"; 81 | break; 82 | } 83 | Logger::Log(LogLevel::Info) << "SignalHandler(" << op_str << ", " << k << ", " << v << ")"; 84 | }); 85 | 86 | Random r; 87 | 88 | std::atomic alive(true); 89 | std::thread t([&]() 90 | { 91 | int size = 5; 92 | int i = 0; 93 | while (alive) 94 | { 95 | sleep_for(seconds(1)); 96 | Logger::Log(LogLevel::Info) << "============="; 97 | dict->Set(i, r.GenerateString(6)); 98 | i = (i + 1) % size; 99 | } 100 | }); 101 | 102 | sleep_for(seconds(10)); 103 | alive = false; 104 | t.join(); 105 | } 106 | catch (const std::exception& ex) 107 | { 108 | Logger::Log(LogLevel::Error) << "Uncaught exception: " << ex.what(); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /examples/observable_dictionary/SortedObservableDictionary.hpp: -------------------------------------------------------------------------------- 1 | #ifndef EXAMPLES_OBSERVABLE_DICTIONARY_SORTEDOBSERVABLEDICTIONARY_HPP 2 | #define EXAMPLES_OBSERVABLE_DICTIONARY_SORTEDOBSERVABLEDICTIONARY_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | 16 | #include "../common/Signals.hpp" 17 | #include "IObservableDictionary.hpp" 18 | 19 | 20 | template < typename Key_, typename Value_ > 21 | class SortedObservableDictionary : public virtual IObservableDictionary 22 | { 23 | using Mutex = std::recursive_mutex; 24 | using Lock = std::lock_guard; 25 | using Listener = IObservableDictionaryListener; 26 | using ListenerPtr = std::shared_ptr; 27 | 28 | private: 29 | std::map _map; 30 | std::shared_ptr _mutex; 31 | SharedRMutexSignal _onChanged; 32 | SharedRMutexListenable _listenable; 33 | 34 | public: 35 | SortedObservableDictionary() 36 | : _mutex(std::make_shared()), 37 | _onChanged(_mutex, [&](const typename decltype(_onChanged)::handler_type& h) { for (auto p : _map) h(CollectionOp::ItemAdded, p.first, p.second); }), 38 | _listenable(_mutex, [&](const ListenerPtr& l) { for (auto p : _map) l->OnItemAdded(p.first, p.second); }) 39 | { } 40 | 41 | virtual std::recursive_mutex& SyncRoot() const 42 | { return *_mutex; } 43 | 44 | virtual wigwag::signal_connector OnChanged() const 45 | { return _onChanged.connector(); } 46 | 47 | virtual wigwag::token AddListener(const IObservableDictionaryListenerPtr& listener) const 48 | { return _listenable.connect(listener); } 49 | 50 | virtual int GetCount() const 51 | { 52 | Lock l(*_mutex); 53 | return _map.size(); 54 | } 55 | 56 | virtual bool IsEmpty() const 57 | { 58 | Lock l(*_mutex); 59 | return _map.empty(); 60 | } 61 | 62 | virtual Value_ Get(const Key_& key) const 63 | { 64 | Lock l(*_mutex); 65 | auto it = _map.find(key); 66 | if (it == _map.end()) 67 | throw std::runtime_error("Key not found!"); 68 | return it->second; 69 | } 70 | 71 | virtual bool ContainsKey(const Key_& key) const 72 | { 73 | Lock l(*_mutex); 74 | return _map.find(key) != _map.end(); 75 | } 76 | 77 | virtual bool TryGet(const Key_& key, Value_& outValue) const 78 | { 79 | Lock l(*_mutex); 80 | auto it = _map.find(key); 81 | if (it == _map.end()) 82 | return false; 83 | outValue = it->second; 84 | return true; 85 | } 86 | 87 | virtual void Set(const Key_& key, const Value_& value) 88 | { 89 | Lock l(*_mutex); 90 | auto it = _map.find(key); 91 | if (it != _map.end()) 92 | { 93 | _onChanged(CollectionOp::ItemRemoved, key, it->second); 94 | _listenable.invoke([&](const ListenerPtr& l) { l->OnItemRemoved(key, it->second); }); 95 | it->second = value; 96 | } 97 | else 98 | _map.insert({key, value}); 99 | 100 | _onChanged(CollectionOp::ItemAdded, key, value); 101 | _listenable.invoke([&](const ListenerPtr& l) { l->OnItemAdded(key, value); }); 102 | } 103 | 104 | virtual void Remove(const Key_& key) 105 | { 106 | if (!TryRemove(key)) 107 | throw std::runtime_error("Key not found!"); 108 | } 109 | 110 | virtual bool TryRemove(const Key_& key) 111 | { 112 | Lock l(*_mutex); 113 | auto it = _map.find(key); 114 | if (it == _map.end()) 115 | return false; 116 | 117 | _onChanged(CollectionOp::ItemRemoved, key, it->second); 118 | _listenable.invoke([&](const ListenerPtr& l) { l->OnItemRemoved(key, it->second); }); 119 | _map.erase(it); 120 | return true; 121 | } 122 | 123 | virtual void Clear() 124 | { 125 | Lock l(*_mutex); 126 | for (auto p : _map) 127 | { 128 | _onChanged(CollectionOp::ItemRemoved, p.first, p.second); 129 | _listenable.invoke([&](const ListenerPtr& l) { l->OnItemRemoved(p.first, p.second); }); 130 | } 131 | _map.clear(); 132 | } 133 | }; 134 | 135 | #endif 136 | -------------------------------------------------------------------------------- /include/wigwag/api_version.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_API_VERSION_HPP 2 | #define WIGWAG_API_VERSION_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | namespace wigwag 15 | { 16 | 17 | template < unsigned Major_, unsigned Minor_ > 18 | struct api_version 19 | { 20 | static const unsigned major = Major_; 21 | static const unsigned minor = Minor_; 22 | }; 23 | 24 | } 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /include/wigwag/detail/annotations.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_DETAIL_ANNOTATIONS_HPP 2 | #define WIGWAG_DETAIL_ANNOTATIONS_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #if defined(WIGWAG_USE_HELGRIND_ANNOTATIONS) && WIGWAG_USE_HELGRIND_ANNOTATIONS 15 | # include 16 | # define WIGWAG_ANNOTATE_HAPPENS_BEFORE(Marker_) do { ANNOTATE_HAPPENS_BEFORE(Marker_); } while (0) 17 | # define WIGWAG_ANNOTATE_HAPPENS_AFTER(Marker_) do { ANNOTATE_HAPPENS_AFTER(Marker_); } while (0) 18 | # define WIGWAG_ANNOTATE_RELEASE(Marker_) do { ANNOTATE_HAPPENS_BEFORE_FORGET_ALL(Marker_); } while (0) 19 | #else 20 | # define WIGWAG_ANNOTATE_HAPPENS_BEFORE(Marker_) do { } while (0) 21 | # define WIGWAG_ANNOTATE_HAPPENS_AFTER(Marker_) do { } while (0) 22 | # define WIGWAG_ANNOTATE_RELEASE(Marker_) do { } while (0) 23 | #endif 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /include/wigwag/detail/async_handler.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_DETAIL_ASYNC_HANDLER_HPP 2 | #define WIGWAG_DETAIL_ASYNC_HANDLER_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | 16 | #include 17 | 18 | 19 | namespace wigwag { 20 | namespace detail 21 | { 22 | 23 | #include 24 | 25 | template < typename Signature_, typename LifeAssurancePolicy_ > 26 | class async_handler 27 | { 28 | using life_checker = typename LifeAssurancePolicy_::life_checker; 29 | using execution_guard = typename LifeAssurancePolicy_::execution_guard; 30 | 31 | private: 32 | std::shared_ptr _worker; 33 | life_checker _life_checker; 34 | std::function _func; 35 | 36 | public: 37 | async_handler(std::shared_ptr worker, life_checker checker, std::function func) 38 | : _worker(std::move(worker)), _life_checker(std::move(checker)), _func(std::move(func)) 39 | { } 40 | 41 | template < typename... Args_ > 42 | void operator() (Args_&&... args) const 43 | { _worker->add_task(std::bind(&async_handler::invoke_func, _life_checker, _func, std::forward(args)...)); } 44 | 45 | private: 46 | template < typename... Args_ > 47 | static void invoke_func(life_checker checker, const std::function& func, Args_&&... args) 48 | { 49 | execution_guard g(checker); 50 | if (g.is_alive()) 51 | func(std::forward(args)...); 52 | } 53 | }; 54 | 55 | #include 56 | 57 | }} 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /include/wigwag/detail/at_scope_exit.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_DETAIL_AT_SCOPE_EXIT_HPP 2 | #define WIGWAG_DETAIL_AT_SCOPE_EXIT_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | 16 | 17 | namespace wigwag { 18 | namespace detail 19 | { 20 | 21 | #include 22 | 23 | template < typename Func_ > 24 | class scope_guard 25 | { 26 | Func_ _f; 27 | bool _moved; 28 | 29 | public: 30 | scope_guard(Func_&& f) 31 | : _f(f), _moved(false) 32 | { } 33 | 34 | scope_guard(scope_guard&& other) 35 | : _f(other._f), _moved(other._moved) 36 | { other._moved = true; } 37 | 38 | ~scope_guard() 39 | { 40 | if (!_moved) 41 | _f(); 42 | } 43 | }; 44 | 45 | template < typename Func_ > 46 | scope_guard at_scope_exit(Func_&& f) 47 | { return scope_guard(std::move(f)); } 48 | 49 | #include 50 | 51 | }} 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /include/wigwag/detail/config.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_DETAIL_CONFIG_HPP 2 | #define WIGWAG_DETAIL_CONFIG_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | 16 | #include 17 | 18 | 19 | #if defined(__GNUC__) || defined(__clang) 20 | # if !defined(__EXCEPTIONS) && !defined(WIGWAG_NOEXCEPTIONS) 21 | # define WIGWAG_NOEXCEPTIONS 1 22 | # endif 23 | 24 | # if !defined(WIGWAG_PLATFORM_POSIX) 25 | # define WIGWAG_PLATFORM_POSIX 1 26 | # endif 27 | #endif 28 | 29 | #if defined(__GNUC__) || defined(__clang) 30 | # define WIGWAG_EXPECT(A_, B_) __builtin_expect((long)(A_), (long)(B_)) 31 | #endif 32 | 33 | #if defined(_MSC_VER) 34 | # if !defined(_CPPUNWIND) && !defined(WIGWAG_NOEXCEPTIONS) 35 | # define WIGWAG_NOEXCEPTIONS 1 36 | # endif 37 | 38 | # if !defined(WIGWAG_PLATFORM_WINDOWS) 39 | # define WIGWAG_PLATFORM_WINDOWS 1 40 | # endif 41 | #endif 42 | 43 | 44 | #if !defined(WIGWAG_DEBUG) 45 | # if defined(NDEBUG) 46 | # define WIGWAG_DEBUG 0 47 | # else 48 | # define WIGWAG_DEBUG 1 49 | # endif 50 | #endif 51 | 52 | 53 | #if !defined(WIGWAG_NOEXCEPTIONS) 54 | # define WIGWAG_NOEXCEPTIONS 0 55 | #endif 56 | 57 | #if !defined(WIGWAG_PLATFORM_POSIX) 58 | # define WIGWAG_PLATFORM_POSIX 0 59 | #endif 60 | 61 | #if !defined(WIGWAG_PLATFORM_WINDOWS) 62 | # define WIGWAG_PLATFORM_WINDOWS 0 63 | #endif 64 | 65 | 66 | #if !defined(WIGWAG_EXPECT) 67 | # define WIGWAG_EXPECT(A_, B_) (A_) 68 | #endif 69 | 70 | 71 | #if _MSC_VER 72 | # define WIGWAG_FUNCTION __FUNCTION__ 73 | #else 74 | # define WIGWAG_FUNCTION __func__ 75 | #endif 76 | 77 | #if !defined(WIGWAG_THROW) 78 | # if WIGWAG_NOEXCEPTIONS 79 | # define WIGWAG_THROW(Msg_) do { fprintf(stderr, "WIGWAG_THROW: %s\nFile: %s:%d\nFunction: %s\n", Msg_, __FILE__, __LINE__, WIGWAG_FUNCTION); std::terminate(); } while (0) 80 | # else 81 | # define WIGWAG_THROW(Msg_) throw std::runtime_error(Msg_) 82 | # endif 83 | #endif 84 | 85 | #if !defined(WIGWAG_ASSERT) 86 | # if WIGWAG_DEBUG 87 | # define WIGWAG_ASSERT(Expr_, Msg_) do { if (!(Expr_)) { fprintf(stderr, "WIGWAG_ASSERT: %s\nFile: %s:%d\nFunction: %s\n", Msg_, __FILE__, __LINE__, WIGWAG_FUNCTION); std::terminate(); } } while (0) 88 | # else 89 | # define WIGWAG_ASSERT(...) do { } while (0) 90 | # endif 91 | #endif 92 | 93 | #if defined(_MSC_VER) && (WIGWAG_NOEXCEPTIONS || _MSC_VER < 1900) 94 | # define WIGWAG_NOEXCEPT 95 | #else 96 | # define WIGWAG_NOEXCEPT noexcept 97 | #endif 98 | 99 | #if defined(_MSC_VER) 100 | # define WIGWAG_HAS_UNRESTRICTED_UNIONS (_MSC_VER >= 1900) 101 | # if _MSC_VER < 1900 102 | # define WIGWAG_ALIGNOF __alignof 103 | # define WIGWAG_PRIVATE_IS_CONSTRUCTIBLE_WORKAROUND public 104 | # else 105 | # define WIGWAG_ALIGNOF alignof 106 | # define WIGWAG_PRIVATE_IS_CONSTRUCTIBLE_WORKAROUND private 107 | # endif 108 | #else 109 | # define WIGWAG_HAS_UNRESTRICTED_UNIONS 1 110 | # define WIGWAG_ALIGNOF alignof 111 | # define WIGWAG_PRIVATE_IS_CONSTRUCTIBLE_WORKAROUND private 112 | #endif 113 | 114 | 115 | #endif 116 | -------------------------------------------------------------------------------- /include/wigwag/detail/coverage.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_DETAIL_COVERAGE_HPP 2 | #define WIGWAG_DETAIL_COVERAGE_HPP 3 | 4 | #define WIGWAG_ASSERT(...) do { } while (0) 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /include/wigwag/detail/creation_storage_adapter.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_DETAIL_CREATION_STORAGE_ADAPTER_HPP 2 | #define WIGWAG_DETAIL_CREATION_STORAGE_ADAPTER_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | 16 | 17 | namespace wigwag { 18 | namespace detail 19 | { 20 | 21 | template < typename Storage_ > 22 | class creation_storage_adapter 23 | { 24 | private: 25 | Storage_ _s; 26 | 27 | public: 28 | creation_storage_adapter() 29 | : _s() 30 | { } 31 | 32 | template < typename T_, typename... Args_ > 33 | void create(Args_&&... args) 34 | { _s.template create(std::forward(args)...); } 35 | 36 | explicit operator bool() const 37 | { return _s.constructed(); } 38 | 39 | auto get_ptr() const -> decltype(_s.get_ptr()) 40 | { return _s.get_ptr(); } 41 | 42 | auto operator -> () const -> decltype(&*_s.get_ptr()) 43 | { return &*_s.get_ptr(); } 44 | }; 45 | 46 | }} 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /include/wigwag/detail/disable_warnings.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016, Dmitry Koplyarov 2 | // 3 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 4 | // provided that the above copyright notice and this permission notice appear in all copies. 5 | // 6 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 7 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 8 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 9 | 10 | 11 | // Disabling some warnings here because fixing them has a performance penalty :( 12 | 13 | #if defined(__GNUC__) || defined(__clang) 14 | # pragma GCC diagnostic push 15 | # pragma GCC diagnostic ignored "-Weffc++" 16 | #endif 17 | 18 | #if defined(_MSC_VER) 19 | # if _MSC_VER >= 1900 20 | # pragma warning(disable: 5031) // Sorry :( 21 | # endif 22 | # pragma warning(push) 23 | # pragma warning(disable: 4355 4625 4626) 24 | # if _MSC_VER >= 1700 && _MSC_VER < 1900 25 | # pragma warning(disable: 4127) 26 | # endif 27 | # if _MSC_VER >= 1900 28 | # pragma warning(disable: 5026 5027) 29 | # endif 30 | #endif 31 | 32 | #if defined(WIGWAG_WARNINGS_DISABLED) 33 | # error Inconsistent disable_warnings.hpp/enable_warnings.hpp includes! 34 | #endif 35 | 36 | #define WIGWAG_WARNINGS_DISABLED 37 | -------------------------------------------------------------------------------- /include/wigwag/detail/enable_warnings.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016, Dmitry Koplyarov 2 | // 3 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 4 | // provided that the above copyright notice and this permission notice appear in all copies. 5 | // 6 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 7 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 8 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 9 | 10 | 11 | #if defined(__GNUC__) || defined(__clang) 12 | # pragma GCC diagnostic pop 13 | #endif 14 | 15 | #if defined(_MSC_VER) 16 | # pragma warning(pop) 17 | # if _MSC_VER >= 1900 18 | # pragma warning(default: 5031) // Sorry :( 19 | # endif 20 | #endif 21 | 22 | #if !defined(WIGWAG_WARNINGS_DISABLED) 23 | # error Inconsistent disable_warnings.hpp/enable_warnings.hpp includes! 24 | #endif 25 | 26 | #undef WIGWAG_WARNINGS_DISABLED 27 | -------------------------------------------------------------------------------- /include/wigwag/detail/enabler.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_DETAIL_ENABLER_HPP 2 | #define WIGWAG_DETAIL_ENABLER_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | namespace wigwag { 15 | namespace detail 16 | { 17 | 18 | template < int > 19 | class basic_enabler 20 | { }; 21 | 22 | using enabler = basic_enabler<0>; 23 | 24 | }} 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /include/wigwag/detail/flags.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_DETAIL_FLAGS_HPP 2 | #define WIGWAG_DETAIL_FLAGS_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | 16 | 17 | namespace wigwag { 18 | namespace detail 19 | { 20 | 21 | #include 22 | 23 | #define WIGWAG_DECLARE_ENUM_BITWISE_OPERATORS(EnumClass_) \ 24 | inline EnumClass_ operator | (EnumClass_ l, EnumClass_ r) \ 25 | { \ 26 | using underlying = std::underlying_type::type; \ 27 | return static_cast(static_cast(l) | static_cast(r)); \ 28 | } \ 29 | inline EnumClass_ operator & (EnumClass_ l, EnumClass_ r) \ 30 | { \ 31 | using underlying = std::underlying_type::type; \ 32 | return static_cast(static_cast(l) & static_cast(r)); \ 33 | } 34 | 35 | template < typename T_ > 36 | inline bool contains_flag(T_ val, T_ flag) 37 | { return (val & flag) != T_(); } 38 | 39 | #include 40 | 41 | }} 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /include/wigwag/detail/intrusive_list.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_DETAIL_INTRUSIVE_LIST_HPP 2 | #define WIGWAG_DETAIL_INTRUSIVE_LIST_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | 16 | #include 17 | #include 18 | 19 | 20 | namespace wigwag { 21 | namespace detail 22 | { 23 | 24 | #include 25 | 26 | template < typename T_ > 27 | class intrusive_list; 28 | 29 | 30 | class intrusive_list_node 31 | { 32 | template < typename T_ > 33 | friend class intrusive_list; 34 | 35 | private: 36 | intrusive_list_node* _prev; 37 | intrusive_list_node* _next; 38 | 39 | public: 40 | intrusive_list_node() : _prev(this), _next(this) { } 41 | 42 | private: 43 | void insert_before(intrusive_list_node& other) 44 | { 45 | _prev = other._prev; 46 | _next = &other; 47 | 48 | _next->_prev = this; 49 | _prev->_next = this; 50 | } 51 | 52 | void unlink() 53 | { 54 | _next->_prev = _prev; 55 | _prev->_next = _next; 56 | _prev = _next = this; 57 | } 58 | 59 | bool unlinked() const 60 | { return _next == this && _prev == this; } 61 | }; 62 | 63 | 64 | template < typename T_ > 65 | class intrusive_list 66 | { 67 | static_assert(std::is_base_of::value, "intrusive_list_node should be a base of T_"); 68 | 69 | public: 70 | class const_iterator; 71 | 72 | class iterator : public iterator_base 73 | { 74 | friend class const_iterator; 75 | 76 | private: 77 | intrusive_list_node* _node; 78 | 79 | public: 80 | explicit iterator(intrusive_list_node* node = nullptr) : _node(node) { } 81 | 82 | T_& dereference() const { return static_cast(*_node); } 83 | bool equal(iterator other) const { return _node == other._node; } 84 | void increment() { _node = _node->_next; } 85 | void decrement() { _node = _node->_prev; } 86 | }; 87 | 88 | class const_iterator : public iterator_base 89 | { 90 | private: 91 | const intrusive_list_node* _node; 92 | 93 | public: 94 | const_iterator(iterator it) : _node(it._node) { } 95 | explicit const_iterator(const intrusive_list_node* node = nullptr) : _node(node) { } 96 | 97 | const T_& dereference() const { return static_cast(*_node); } 98 | bool equal(const_iterator other) const { return _node == other._node; } 99 | void increment() { _node = _node->_next; } 100 | void decrement() { _node = _node->_prev; } 101 | }; 102 | 103 | private: 104 | intrusive_list_node _root; 105 | 106 | public: 107 | iterator begin() { return iterator(_root._next); } 108 | iterator end() { return iterator(&_root); } 109 | iterator pre_end() { return iterator(_root._prev); } 110 | 111 | const_iterator begin() const { return const_iterator(_root._next); } 112 | const_iterator end() const { return const_iterator(&_root); } 113 | const_iterator pre_end() const { return const_iterator(_root._prev); } 114 | 115 | bool empty() const { return _root.unlinked(); } 116 | size_t size() const { return std::distance(begin(), end()); } 117 | 118 | void push_back(T_& node) { node.insert_before(_root); } 119 | void erase(T_& node) { node.unlink(); } 120 | }; 121 | 122 | #include 123 | 124 | }} 125 | 126 | #endif 127 | -------------------------------------------------------------------------------- /include/wigwag/detail/intrusive_ptr.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_DETAIL_INTRUSIVE_PTR_HPP 2 | #define WIGWAG_DETAIL_INTRUSIVE_PTR_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | #include 16 | 17 | #include 18 | 19 | 20 | namespace wigwag { 21 | namespace detail 22 | { 23 | 24 | #include 25 | 26 | template < typename T_ > 27 | class intrusive_ptr 28 | { 29 | template < typename U_ > 30 | friend class intrusive_ptr; 31 | 32 | private: 33 | T_* _raw; 34 | 35 | public: 36 | explicit intrusive_ptr(T_* rawPtr = nullptr) 37 | : _raw(rawPtr) 38 | { } 39 | 40 | intrusive_ptr(intrusive_ptr&& other) WIGWAG_NOEXCEPT 41 | : _raw(other._raw) 42 | { other._raw = nullptr; } 43 | 44 | template < typename U_ > 45 | intrusive_ptr(const intrusive_ptr other, typename std::enable_if::value, enabler>::type = enabler()) 46 | : _raw(other._raw) 47 | { 48 | if (_raw) 49 | _raw->add_ref(); 50 | } 51 | 52 | intrusive_ptr(const intrusive_ptr& other) 53 | : _raw(other._raw) 54 | { 55 | if (_raw) 56 | _raw->add_ref(); 57 | } 58 | 59 | ~intrusive_ptr() 60 | { 61 | if (_raw) 62 | _raw->release(); 63 | } 64 | 65 | intrusive_ptr& operator = (intrusive_ptr&& other) 66 | { 67 | intrusive_ptr tmp(std::move(other)); 68 | swap(tmp); 69 | return *this; 70 | } 71 | 72 | intrusive_ptr& operator = (const intrusive_ptr& other) 73 | { 74 | intrusive_ptr tmp(other); 75 | swap(tmp); 76 | return *this; 77 | } 78 | 79 | bool operator == (const intrusive_ptr& other) const 80 | { return other._raw == _raw; } 81 | 82 | bool operator != (const intrusive_ptr& other) const 83 | { return !(*this == other); } 84 | 85 | explicit operator bool() const 86 | { return _raw != nullptr; } 87 | 88 | void reset(T_* ptr = nullptr) 89 | { 90 | intrusive_ptr tmp(ptr); 91 | swap(tmp); 92 | } 93 | 94 | void swap(intrusive_ptr& other) 95 | { std::swap(_raw, other._raw); } 96 | 97 | T_* get() const 98 | { return _raw; } 99 | 100 | T_* operator -> () const 101 | { return _raw; } 102 | 103 | T_& operator * () const 104 | { return *_raw; } 105 | }; 106 | 107 | #include 108 | 109 | }} 110 | 111 | #endif 112 | -------------------------------------------------------------------------------- /include/wigwag/detail/intrusive_ref_counter.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_DETAIL_INTRUSIVE_REF_COUNTER_HPP 2 | #define WIGWAG_DETAIL_INTRUSIVE_REF_COUNTER_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | 16 | 17 | namespace wigwag { 18 | namespace detail 19 | { 20 | 21 | #include 22 | 23 | template < typename RefCounterPolicy_, typename Derived_ > 24 | class intrusive_ref_counter : private RefCounterPolicy_ 25 | { 26 | public: 27 | intrusive_ref_counter() 28 | : RefCounterPolicy_(1) 29 | { } 30 | 31 | intrusive_ref_counter(const intrusive_ref_counter&) = delete; 32 | intrusive_ref_counter& operator = (const intrusive_ref_counter&) = delete; 33 | 34 | void add_ref() const 35 | { RefCounterPolicy_::add_ref(); } 36 | 37 | void release() const 38 | { 39 | if (RefCounterPolicy_::release() == 0) 40 | delete static_cast(this); 41 | } 42 | }; 43 | 44 | #include 45 | 46 | }} 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /include/wigwag/detail/iterator_base.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_DETAIL_ITERATOR_BASE_HPP 2 | #define WIGWAG_DETAIL_ITERATOR_BASE_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | #include 16 | 17 | 18 | namespace wigwag { 19 | namespace detail 20 | { 21 | 22 | #include 23 | 24 | template < 25 | typename Derived_, 26 | typename Category_, 27 | typename T_, 28 | typename Distance_ = std::ptrdiff_t, 29 | typename Pointer_ = T_*, 30 | typename Reference_ = T_& 31 | > 32 | class iterator_base : public std::iterator 33 | { 34 | public: 35 | bool operator == (Derived_ other) const { return get_derived().equal(other); } 36 | bool operator != (Derived_ other) const { return !(*this == other); } 37 | 38 | bool operator < (Derived_ other) const { return get_derived().distance_to(other) < 0; } 39 | bool operator > (Derived_ other) const { return get_derived().distance_to(other) > 0; } 40 | bool operator <= (Derived_ other) const { return !(other < *this); } 41 | bool operator >= (Derived_ other) const { return !(other > *this); } 42 | 43 | Reference_ operator * () { return get_derived().dereference(); } 44 | const Reference_ operator * () const { return get_derived().dereference(); } 45 | 46 | Pointer_ operator -> () { return &(get_derived().dereference()); } 47 | const Pointer_ operator -> () const { return &(get_derived().dereference()); } 48 | 49 | Derived_& operator ++ () { get_derived().increment(); return get_derived(); } 50 | Derived_ operator ++ (int) { Derived_ tmp(get_derived()); ++*this; return tmp; } 51 | 52 | Derived_& operator -- () { get_derived().decrement(); return get_derived(); } 53 | Derived_ operator -- (int) { Derived_ tmp(get_derived()); --*this; return tmp; } 54 | 55 | Derived_& operator += (Distance_ n) { get_derived().advance(n); return get_derived(); } 56 | Derived_& operator -= (Distance_ n) { get_derived().advance(-n); return get_derived(); } 57 | 58 | Distance_ operator - (Derived_ other) const { return other.distance_to(get_derived()); } 59 | 60 | Derived_ operator + (Distance_ n) const { Derived_ tmp(get_derived()); return tmp += n; } 61 | Derived_ operator - (Distance_ n) const { Derived_ tmp(get_derived()); return tmp -= n; } 62 | 63 | Reference_ operator[] (Distance_ n) const { Derived_ tmp(get_derived()); tmp.advance(n); return tmp.dereference(); } 64 | 65 | protected: 66 | Derived_& get_derived() { return static_cast(*this); } 67 | const Derived_& get_derived() const { return static_cast(*this); } 68 | }; 69 | 70 | 71 | template < typename Derived_, typename Category_, typename T_, typename Distance_, typename Pointer_, typename Reference_ > 72 | Derived_ operator + (Distance_ n, iterator_base it) 73 | { return it + n; } 74 | 75 | 76 | #include 77 | 78 | }} 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /include/wigwag/detail/policies/creation/policy_concept.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_POLICIES_CREATION_POLICY_CONCEPT_HPP 2 | #define WIGWAG_POLICIES_CREATION_POLICY_CONCEPT_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | 19 | namespace wigwag { 20 | namespace detail { 21 | namespace creation 22 | { 23 | 24 | template < typename T_ > 25 | struct check_policy_v2_0 26 | { using adapted_policy = typename policy_adapter>, T_>::type; }; 27 | 28 | 29 | template < typename T_ > 30 | struct policy_concept 31 | { 32 | using adapted_policy = typename wigwag::detail::policy_version_detector>::adapted_policy; 33 | }; 34 | 35 | }}} 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /include/wigwag/detail/policies/exception_handling/policy_concept.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_POLICIES_EXCEPTION_HANDLING_POLICY_CONCEPT_HPP 2 | #define WIGWAG_POLICIES_EXCEPTION_HANDLING_POLICY_CONCEPT_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | 20 | 21 | namespace wigwag { 22 | namespace detail { 23 | namespace exception_handling 24 | { 25 | 26 | #include 27 | 28 | template < typename T_ > 29 | struct check_policy_v2_0 30 | { using adapted_policy = typename policy_adapter>, T_>::type; }; 31 | 32 | 33 | template < typename T_ > 34 | struct policy_concept 35 | { 36 | using adapted_policy = typename wigwag::detail::policy_version_detector>::adapted_policy; 37 | }; 38 | 39 | #include 40 | 41 | }}} 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /include/wigwag/detail/policies/life_assurance/policy_concept.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_POLICIES_LIFE_ASSURANCE_CONCEPT_HPP 2 | #define WIGWAG_POLICIES_LIFE_ASSURANCE_CONCEPT_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | #include 16 | 17 | 18 | namespace wigwag { 19 | namespace detail { 20 | namespace life_assurance 21 | { 22 | 23 | #include 24 | 25 | template < typename T_ > 26 | struct check_policy_v2_0 27 | { using adapted_policy = typename policy_adapter>, T_>::type; }; 28 | 29 | 30 | template < typename T_ > 31 | struct policy_concept 32 | { 33 | using adapted_policy = typename wigwag::detail::policy_version_detector>::adapted_policy; 34 | }; 35 | 36 | #include 37 | 38 | }}} 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /include/wigwag/detail/policies/ref_counter/policy_concept.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_POLICIES_REF_COUNTER_POLICY_CONCEPT_HPP 2 | #define WIGWAG_POLICIES_REF_COUNTER_POLICY_CONCEPT_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | #include 16 | 17 | 18 | namespace wigwag { 19 | namespace detail { 20 | namespace ref_counter 21 | { 22 | 23 | #include 24 | 25 | template < typename T_ > 26 | struct check_policy_v2_0 27 | { using adapted_policy = typename policy_adapter>, T_>::type; }; 28 | 29 | 30 | template < typename T_ > 31 | struct policy_concept 32 | { 33 | using adapted_policy = typename wigwag::detail::policy_version_detector>::adapted_policy; 34 | }; 35 | 36 | #include 37 | 38 | }}} 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /include/wigwag/detail/policies/state_populating/policy_concept.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_POLICIES_STATE_POPULATING_POLICY_CONCEPT_HPP 2 | #define WIGWAG_POLICIES_STATE_POPULATING_POLICY_CONCEPT_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | #include 20 | 21 | 22 | namespace wigwag { 23 | namespace detail { 24 | namespace state_populating 25 | { 26 | 27 | #include 28 | 29 | template < typename T_ > 30 | struct check_policy_v2_0 31 | { using adapted_policy = typename policy_adapter>, T_>::type; }; 32 | 33 | 34 | template < typename T_ > 35 | struct policy_concept 36 | { using adapted_policy = typename wigwag::detail::policy_version_detector>::adapted_policy; }; 37 | 38 | #include 39 | 40 | }}} 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /include/wigwag/detail/policies/threading/policy_concept.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_POLICIES_THREADING_POLICY_CONCEPT_HPP 2 | #define WIGWAG_POLICIES_THREADING_POLICY_CONCEPT_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | 19 | namespace wigwag { 20 | namespace detail { 21 | namespace threading 22 | { 23 | 24 | #include 25 | 26 | template < typename T_ > 27 | struct check_policy_v2_0 28 | { using adapted_policy = typename policy_adapter>, T_>::type; }; 29 | 30 | 31 | template < typename T_ > 32 | struct policy_concept 33 | { 34 | using adapted_policy = typename wigwag::detail::policy_version_detector>::adapted_policy; 35 | }; 36 | 37 | #include 38 | 39 | }}} 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /include/wigwag/detail/policies_concepts.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_DETAIL_POLICIES_CONCEPTS_HPP 2 | #define WIGWAG_DETAIL_POLICIES_CONCEPTS_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /include/wigwag/detail/policy_picker.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_DETAIL_POLICY_PICKER_HPP 2 | #define WIGWAG_DETAIL_POLICY_PICKER_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | 16 | 17 | namespace wigwag { 18 | namespace detail 19 | { 20 | 21 | #include 22 | 23 | template < template class PolicyConcept_, typename DefaultPolicy_ > 24 | struct policies_config_entry 25 | { 26 | template < typename T_ > using concept = PolicyConcept_; 27 | using default_policy = DefaultPolicy_; 28 | }; 29 | 30 | 31 | template < typename... Entries_ > 32 | struct policies_config 33 | { 34 | template < typename Policy_ > 35 | using policy_supported = std::false_type; 36 | 37 | template < template class Concept_ > 38 | using default_policy = void; 39 | }; 40 | 41 | template < typename EntriesHead_, typename... Entries_ > 42 | struct policies_config 43 | { 44 | template < typename Policy_ > 45 | using policy_supported = typename std::conditional< 46 | !std::is_same::adapted_policy, void>::value, 47 | std::true_type, 48 | typename policies_config::template policy_supported 49 | >::type; 50 | 51 | template < template class Concept_ > 52 | using default_policy = typename std::conditional< 53 | std::is_same, Concept_>::value, 54 | typename EntriesHead_::default_policy, 55 | typename policies_config::template default_policy 56 | >::type; 57 | }; 58 | 59 | 60 | template < 61 | template class PolicyConcept_, 62 | typename PoliciesConfig_, 63 | typename... Policies_ > 64 | struct policy_picker 65 | { using type = typename PoliciesConfig_::template default_policy; }; 66 | 67 | template < 68 | template class PolicyConcept_, 69 | typename PoliciesConfig_, 70 | typename PoliciesHead_, 71 | typename... Policies_ > 72 | struct policy_picker 73 | { 74 | static_assert(PoliciesConfig_::template policy_supported::value, "Unexpected policy!"); 75 | 76 | using type = typename std::conditional< 77 | !std::is_same::adapted_policy, void>::value, 78 | typename PolicyConcept_::adapted_policy, 79 | typename policy_picker::type>::type; 80 | }; 81 | 82 | #include 83 | 84 | }} 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /include/wigwag/detail/policy_version_detector.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_DETAIL_POLICY_VERSION_DETECTOR_HPP 2 | #define WIGWAG_DETAIL_POLICY_VERSION_DETECTOR_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | 16 | 17 | namespace wigwag { 18 | namespace detail 19 | { 20 | 21 | #include 22 | 23 | 24 | template < typename T_, typename Tag_, typename AdaptedT_ > 25 | struct policy_adapter 26 | { using type = typename std::conditional::value, T_, void>::type; }; 27 | 28 | template < typename... VersionChecks_ > 29 | struct policy_version_detector 30 | { 31 | using adapted_policy = void; 32 | }; 33 | 34 | 35 | template < typename HeadVersionCheck_, typename... TailVersionChecks_ > 36 | struct policy_version_detector 37 | { 38 | using adapted_policy = typename std::conditional< 39 | std::is_same::value, 40 | typename policy_version_detector::adapted_policy, 41 | typename HeadVersionCheck_::adapted_policy 42 | >::type; 43 | }; 44 | 45 | #include 46 | 47 | }} 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /include/wigwag/detail/signal_connector_impl.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_DETAIL_SIGNAL_CONNECTOR_IMPL_HPP 2 | #define WIGWAG_DETAIL_SIGNAL_CONNECTOR_IMPL_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | 19 | namespace wigwag { 20 | namespace detail 21 | { 22 | 23 | #include 24 | 25 | template < typename Signature_ > 26 | struct signal_connector_impl 27 | { 28 | virtual ~signal_connector_impl() { } 29 | 30 | virtual token connect(std::function handler, handler_attributes attributes) = 0; 31 | virtual token connect(std::shared_ptr worker, std::function handler, handler_attributes attributes) = 0; 32 | 33 | virtual void add_ref() = 0; 34 | virtual void release() = 0; 35 | }; 36 | 37 | #include 38 | 39 | }} 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /include/wigwag/detail/stdcpp_annotations.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_DETAIL_STDCPP_ANNOTATIONS_HPP 2 | #define WIGWAG_DETAIL_STDCPP_ANNOTATIONS_HPP 3 | 4 | #include 5 | 6 | #define _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(Marker_) ANNOTATE_HAPPENS_BEFORE(Marker_) 7 | #define _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(Marker_) ANNOTATE_HAPPENS_AFTER(Marker_) 8 | #define _GLIBCXX_EXTERN_TEMPLATE -1 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /include/wigwag/detail/storage_for.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_DETAIL_STORAGE_FOR_HPP 2 | #define WIGWAG_DETAIL_STORAGE_FOR_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | 16 | #include 17 | #include 18 | 19 | 20 | namespace wigwag { 21 | namespace detail 22 | { 23 | 24 | #include 25 | 26 | #if WIGWAG_HAS_UNRESTRICTED_UNIONS 27 | template < typename T_ > 28 | union storage_for 29 | { 30 | public: 31 | struct no_construct_tag { }; 32 | 33 | private: 34 | T_ obj; 35 | 36 | public: 37 | storage_for(no_construct_tag) { } 38 | 39 | template < typename... Args_ > 40 | storage_for(Args_&&... args) : obj(std::forward(args)...) { } 41 | ~storage_for() { } 42 | 43 | template < typename... Args_ > 44 | void construct(Args_&&... args) 45 | { new(&obj) T_(std::forward(args)...); } 46 | 47 | void destruct() 48 | { obj.~T_(); } 49 | 50 | T_& ref() { return obj; } 51 | const T_& ref() const { return obj; } 52 | }; 53 | #else 54 | template < typename T_ > 55 | class storage_for 56 | { 57 | public: 58 | struct no_construct_tag { }; 59 | 60 | private: 61 | using storage = typename std::aligned_storage::type; 62 | 63 | private: 64 | storage obj; 65 | 66 | public: 67 | storage_for(no_construct_tag) { } 68 | 69 | template < typename... Args_ > 70 | storage_for(Args_&&... args) { new(&obj) T_(std::forward(args)...); } 71 | ~storage_for() { } 72 | 73 | template < typename... Args_ > 74 | void construct(Args_&&... args) 75 | { new(&obj) T_(std::forward(args)...); } 76 | 77 | void destruct() 78 | { obj.~T_(); } 79 | 80 | T_& ref() { return *reinterpret_cast(&obj); } 81 | const T_& ref() const { return *reinterpret_cast(&obj); } 82 | }; 83 | #endif 84 | 85 | #include 86 | 87 | }} 88 | 89 | #endif 90 | -------------------------------------------------------------------------------- /include/wigwag/detail/type_expression_check.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_DETAIL_TYPE_EXPRESSION_CHECK_HPP 2 | #define WIGWAG_DETAIL_TYPE_EXPRESSION_CHECK_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | 16 | 17 | namespace wigwag { 18 | namespace detail 19 | { 20 | 21 | #define WIGWAG_DECLARE_TYPE_EXPRESSION_CHECK(Name_, ...) \ 22 | template < typename T_, typename Enabler = std::true_type > \ 23 | struct Name_ \ 24 | { static const bool value = false; }; \ 25 | template < typename T_ > \ 26 | struct Name_ \ 27 | { static const bool value = true; } 28 | 29 | }} 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /include/wigwag/handler_attributes.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_HANDLER_ATTRIBUTES_HPP 2 | #define WIGWAG_HANDLER_ATTRIBUTES_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | 16 | 17 | namespace wigwag 18 | { 19 | 20 | #include 21 | 22 | enum class handler_attributes 23 | { 24 | none = 0x0, 25 | suppress_populator = 0x1 26 | }; 27 | 28 | WIGWAG_DECLARE_ENUM_BITWISE_OPERATORS(handler_attributes) 29 | 30 | #include 31 | 32 | } 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /include/wigwag/life_token.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_LIFE_TOKEN_HPP 2 | #define WIGWAG_LIFE_TOKEN_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | #include 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | 23 | namespace wigwag 24 | { 25 | 26 | #include 27 | 28 | class life_token 29 | { 30 | private: 31 | using int_type = unsigned int; 32 | static const int_type alive_flag = ((int_type)1) << (std::numeric_limits::digits - 1); 33 | 34 | struct impl 35 | { 36 | std::atomic lock_counter_and_alive_flag; 37 | std::condition_variable cond_var; 38 | std::mutex mutex; 39 | 40 | impl() : lock_counter_and_alive_flag(alive_flag) { } 41 | }; 42 | using impl_ptr = std::shared_ptr; 43 | 44 | public: 45 | class checker; 46 | class execution_guard; 47 | 48 | private: 49 | impl_ptr _impl; 50 | bool _released; 51 | 52 | public: 53 | life_token() 54 | : _impl(std::make_shared()), _released(false) 55 | { } 56 | 57 | life_token(life_token&& other) WIGWAG_NOEXCEPT 58 | : _impl(other._impl), _released(false) 59 | { other._released = true; } 60 | 61 | ~life_token() 62 | { release(); } 63 | 64 | void release() 65 | { 66 | if (_released) 67 | return; 68 | 69 | _impl->lock_counter_and_alive_flag -= alive_flag; 70 | std::unique_lock l(_impl->mutex); 71 | while (_impl->lock_counter_and_alive_flag != 0) 72 | _impl->cond_var.wait(l); 73 | 74 | _released = true; 75 | } 76 | 77 | life_token(const life_token&) = delete; 78 | life_token& operator = (const life_token&) = delete; 79 | }; 80 | 81 | 82 | class life_token::checker 83 | { 84 | friend class execution_guard; 85 | 86 | private: 87 | impl_ptr _impl; 88 | 89 | public: 90 | checker(const life_token& token) WIGWAG_NOEXCEPT 91 | : _impl(token._impl) 92 | { } 93 | }; 94 | 95 | 96 | class life_token::execution_guard 97 | { 98 | private: 99 | impl_ptr _impl; 100 | int _alive; 101 | 102 | public: 103 | execution_guard(const life_token& token) 104 | : _impl(token._impl), _alive(++_impl->lock_counter_and_alive_flag & alive_flag) 105 | { 106 | if (!_alive) 107 | unlock(); 108 | } 109 | 110 | execution_guard(const life_token::checker& checker) 111 | : _impl(checker._impl), _alive(++_impl->lock_counter_and_alive_flag & alive_flag) 112 | { 113 | if (!_alive) 114 | unlock(); 115 | } 116 | 117 | ~execution_guard() 118 | { 119 | if (_alive) 120 | unlock(); 121 | } 122 | 123 | int is_alive() const 124 | { return _alive; } 125 | 126 | private: 127 | void unlock() 128 | { 129 | int_type i = --_impl->lock_counter_and_alive_flag; 130 | if (i == 0) 131 | { 132 | WIGWAG_ANNOTATE_HAPPENS_AFTER(&_impl->lock_counter_and_alive_flag); 133 | WIGWAG_ANNOTATE_RELEASE(&_impl->lock_counter_and_alive_flag); 134 | 135 | std::unique_lock l(_impl->mutex); 136 | _impl->cond_var.notify_all(); 137 | } 138 | else 139 | WIGWAG_ANNOTATE_HAPPENS_BEFORE(&_impl->lock_counter_and_alive_flag); 140 | } 141 | }; 142 | 143 | #include 144 | 145 | } 146 | 147 | #endif 148 | -------------------------------------------------------------------------------- /include/wigwag/listenable.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_LISTENABLE_HPP 2 | #define WIGWAG_LISTENABLE_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | 21 | namespace wigwag 22 | { 23 | 24 | #include 25 | 26 | namespace detail 27 | { 28 | using listenable_policies_config = policies_config< 29 | policies_config_entry, 30 | policies_config_entry, 31 | policies_config_entry, 32 | policies_config_entry, 33 | policies_config_entry, 34 | policies_config_entry 35 | >; 36 | } 37 | 38 | 39 | template < 40 | typename ListenerType_, 41 | typename... Policies_ 42 | > 43 | class listenable : 44 | private detail::policy_picker::type 45 | { 46 | template < template class PolicyConcept_ > 47 | using policy = typename detail::policy_picker::type; 48 | 49 | using exception_handling_policy = policy; 50 | using threading_policy = policy; 51 | using state_populating_policy = policy; 52 | using life_assurance_policy = policy; 53 | using creation_policy = policy; 54 | using ref_counter_policy = policy; 55 | 56 | public: 57 | using listener_type = ListenerType_; 58 | 59 | WIGWAG_PRIVATE_IS_CONSTRUCTIBLE_WORKAROUND: 60 | using impl_type = detail::listenable_impl; 61 | using impl_type_ptr = detail::intrusive_ptr; 62 | 63 | private: 64 | using storage = typename creation_policy::template storage; 65 | 66 | private: 67 | detail::creation_storage_adapter _impl; 68 | 69 | public: 70 | template < bool E_ = std::is_constructible::value, typename = typename std::enable_if::type> 71 | listenable() 72 | { _impl.template create(); } 73 | 74 | template < typename Arg0_, typename... Args_ > 75 | listenable(Arg0_&& arg0, Args_&&... args) 76 | { _impl.template create(std::forward(arg0), std::forward(args)...); } 77 | 78 | ~listenable() 79 | { 80 | if (_impl) 81 | { 82 | _impl->get_lock_primitive().lock_nonrecursive(); 83 | auto sg = detail::at_scope_exit([&] { _impl->get_lock_primitive().unlock_nonrecursive(); } ); 84 | 85 | _impl->finalize_nodes(); 86 | } 87 | } 88 | 89 | listenable(const listenable&) = delete; 90 | listenable& operator = (const listenable&) = delete; 91 | 92 | auto lock_primitive() const -> decltype(_impl->get_lock_primitive().get_primitive()) 93 | { return _impl->get_lock_primitive().get_primitive(); } 94 | 95 | token connect(ListenerType_ handler, handler_attributes attributes = handler_attributes::none) const 96 | { return _impl->connect(std::move(handler), attributes); } 97 | 98 | template < typename InvokeListenerFunc_ > 99 | void invoke(InvokeListenerFunc_&& invoke_listener_func) const 100 | { 101 | if (_impl) 102 | _impl->invoke(invoke_listener_func); 103 | } 104 | }; 105 | 106 | #include 107 | 108 | } 109 | 110 | #endif 111 | -------------------------------------------------------------------------------- /include/wigwag/policies.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_POLICIES_HPP 2 | #define WIGWAG_POLICIES_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /include/wigwag/policies/creation/ahead_of_time.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_POLICIES_CREATION_AHEAD_OF_TIME_HPP 2 | #define WIGWAG_POLICIES_CREATION_AHEAD_OF_TIME_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | 16 | #include 17 | 18 | 19 | namespace wigwag { 20 | namespace creation 21 | { 22 | 23 | #include 24 | 25 | struct ahead_of_time 26 | { 27 | using tag = creation::tag>; 28 | 29 | template < typename OwningPtr_, typename DefaultType_ > 30 | class storage 31 | { 32 | private: 33 | OwningPtr_ _ptr; 34 | 35 | public: 36 | template < typename T_, typename... Args_ > 37 | void create(Args_&&... args) 38 | { _ptr.reset(new T_(std::forward(args)...)); } 39 | 40 | const OwningPtr_& get_ptr() const 41 | { return _ptr; } 42 | 43 | bool constructed() const 44 | { return (bool)_ptr; } 45 | }; 46 | }; 47 | 48 | #include 49 | 50 | }} 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /include/wigwag/policies/creation/lazy.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_POLICIES_CREATION_LAZY_HPP 2 | #define WIGWAG_POLICIES_CREATION_LAZY_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | #include 16 | 17 | #include 18 | 19 | 20 | namespace wigwag { 21 | namespace creation 22 | { 23 | 24 | #include 25 | 26 | struct lazy 27 | { 28 | using tag = creation::tag>; 29 | 30 | template < typename OwningPtr_, typename DefaultType_ > 31 | class storage 32 | { 33 | private: 34 | mutable OwningPtr_ _ptr; 35 | 36 | public: 37 | template < typename T_, bool enable = std::is_same::value && std::is_constructible::value, typename = typename std::enable_if::type > 38 | void create() 39 | { } 40 | 41 | template < typename T_, typename... Args_ > 42 | void create(Args_&&... args) 43 | { _ptr.reset(new T_(std::forward(args)...)); } 44 | 45 | const OwningPtr_& get_ptr() const 46 | { 47 | ensure_created(); 48 | return _ptr; 49 | } 50 | 51 | bool constructed() const 52 | { return (bool)_ptr; } 53 | 54 | private: 55 | template < bool E_ = std::is_constructible::value> 56 | void ensure_created(typename std::enable_if::type = wigwag::detail::enabler()) const 57 | { 58 | if (!_ptr) 59 | _ptr.reset(new DefaultType_()); 60 | } 61 | 62 | template < bool E_ = std::is_constructible::value> 63 | void ensure_created(typename std::enable_if::type = wigwag::detail::enabler()) const 64 | { WIGWAG_ASSERT(_ptr, "Internal wigwag error, _ptr must have been initialized before!"); } 65 | }; 66 | }; 67 | 68 | #include 69 | 70 | }} 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /include/wigwag/policies/creation/policies.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_POLICIES_CREATION_POLICIES_HPP 2 | #define WIGWAG_POLICIES_CREATION_POLICIES_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | #include 16 | 17 | 18 | namespace wigwag { 19 | namespace creation 20 | { 21 | 22 | using default_ = ahead_of_time; 23 | 24 | }} 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /include/wigwag/policies/creation/tag.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_POLICIES_CREATION_TAG_HPP 2 | #define WIGWAG_POLICIES_CREATION_TAG_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | 16 | 17 | namespace wigwag { 18 | namespace creation 19 | { 20 | 21 | template < typename Version_ > 22 | struct tag 23 | { using version = Version_; }; 24 | 25 | }} 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /include/wigwag/policies/exception_handling/none.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_POLICIES_EXCEPTION_HANDLING_NONE_HPP 2 | #define WIGWAG_POLICIES_EXCEPTION_HANDLING_NONE_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | 16 | #include 17 | 18 | 19 | namespace wigwag { 20 | namespace exception_handling 21 | { 22 | 23 | #include 24 | 25 | struct none 26 | { 27 | using tag = exception_handling::tag>; 28 | 29 | template < typename Func_, typename... Args_ > 30 | void handle_exceptions(Func_&& func, Args_&&... args) const 31 | { func(std::forward(args)...); } 32 | }; 33 | 34 | #include 35 | 36 | }} 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /include/wigwag/policies/exception_handling/policies.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_POLICIES_EXCEPTION_HANDLING_POLICIES_HPP 2 | #define WIGWAG_POLICIES_EXCEPTION_HANDLING_POLICIES_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | #include 16 | 17 | namespace wigwag { 18 | namespace exception_handling 19 | { 20 | 21 | using default_ = none; 22 | 23 | }} 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /include/wigwag/policies/exception_handling/print_to_stderr.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_POLICIES_EXCEPTION_HANDLING_PRINT_TO_STDERR_HPP 2 | #define WIGWAG_POLICIES_EXCEPTION_HANDLING_PRINT_TO_STDERR_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | 16 | #include 17 | #include 18 | 19 | #include 20 | 21 | 22 | namespace wigwag { 23 | namespace exception_handling 24 | { 25 | 26 | #include 27 | 28 | #if !WIGWAG_NOEXCEPTIONS 29 | struct print_to_stderr 30 | { 31 | using tag = exception_handling::tag>; 32 | 33 | template < typename Func_, typename... Args_ > 34 | void handle_exceptions(Func_&& func, Args_&&... args) const 35 | { 36 | try 37 | { func(std::forward(args)...); } 38 | catch (const std::exception& ex) 39 | { fprintf(stderr, "Uncaught std::exception: %s\n", ex.what()); } 40 | } 41 | }; 42 | #endif 43 | 44 | #include 45 | 46 | }} 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /include/wigwag/policies/exception_handling/tag.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_POLICIES_EXCEPTION_HANDLING_TAG_HPP 2 | #define WIGWAG_POLICIES_EXCEPTION_HANDLING_TAG_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | 16 | 17 | namespace wigwag { 18 | namespace exception_handling 19 | { 20 | 21 | template < typename Version_ > 22 | struct tag 23 | { using version = Version_; }; 24 | 25 | }} 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /include/wigwag/policies/life_assurance/intrusive_life_tokens.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_POLICIES_LIFE_ASSURANCE_INTRUSIVE_LIFE_TOKENS_HPP 2 | #define WIGWAG_POLICIES_LIFE_ASSURANCE_INTRUSIVE_LIFE_TOKENS_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | 24 | namespace wigwag { 25 | namespace life_assurance 26 | { 27 | 28 | #include 29 | 30 | struct intrusive_life_tokens 31 | { 32 | using tag = life_assurance::tag>; 33 | 34 | class life_assurance; 35 | class life_checker; 36 | class execution_guard; 37 | 38 | 39 | class shared_data 40 | { 41 | friend class life_assurance; 42 | friend class execution_guard; 43 | 44 | private: 45 | mutable std::condition_variable _cond_var; 46 | mutable std::mutex _mutex; 47 | }; 48 | 49 | 50 | class life_assurance 51 | { 52 | friend class life_checker; 53 | friend class execution_guard; 54 | 55 | using int_type = unsigned int; 56 | static const int_type alive_flag = ((int_type)1) << (std::numeric_limits::digits - 1); 57 | 58 | mutable std::atomic _lock_counter_and_alive_flag; 59 | mutable std::atomic _ref_count; 60 | 61 | public: 62 | life_assurance() 63 | : _lock_counter_and_alive_flag(alive_flag), _ref_count(2) // One ref in signal, another in token 64 | { } 65 | 66 | virtual ~life_assurance() 67 | { } 68 | 69 | life_assurance(const life_assurance&) = delete; 70 | life_assurance& operator = (const life_assurance&) = delete; 71 | 72 | 73 | void add_ref() const 74 | { ++_ref_count; } 75 | 76 | void release() const 77 | { 78 | if (release_node()) 79 | delete this; 80 | } 81 | 82 | void release_life_assurance(const shared_data& sd) 83 | { 84 | _lock_counter_and_alive_flag -= alive_flag; 85 | std::unique_lock l(sd._mutex); 86 | while (_lock_counter_and_alive_flag != 0) 87 | sd._cond_var.wait(l); 88 | } 89 | 90 | bool node_should_be_released() const 91 | { return _ref_count == 1; } 92 | 93 | bool release_node() const 94 | { 95 | if (--_ref_count == 0) 96 | { 97 | WIGWAG_ANNOTATE_HAPPENS_AFTER(this); 98 | WIGWAG_ANNOTATE_RELEASE(this); 99 | 100 | return true; 101 | } 102 | else 103 | { 104 | WIGWAG_ANNOTATE_HAPPENS_BEFORE(this); 105 | return false; 106 | } 107 | } 108 | }; 109 | 110 | 111 | class life_checker 112 | { 113 | friend class execution_guard; 114 | 115 | const shared_data* _sd; 116 | wigwag::detail::intrusive_ptr _la; 117 | 118 | public: 119 | life_checker(const shared_data& sd, const life_assurance& la) WIGWAG_NOEXCEPT 120 | : _sd(&sd), _la(&la) 121 | { la.add_ref(); } 122 | }; 123 | 124 | class execution_guard 125 | { 126 | const shared_data& _sd; 127 | const life_assurance* _la; 128 | life_assurance::int_type _alive; 129 | 130 | public: 131 | execution_guard(const life_checker& c) 132 | : _sd(*c._sd), _la(c._la.get()), _alive(++c._la->_lock_counter_and_alive_flag & life_assurance::alive_flag) 133 | { 134 | if (!_alive) 135 | unlock(); 136 | } 137 | 138 | execution_guard(const shared_data& sd, const life_assurance& la) 139 | : _sd(sd), _la(&la), _alive(++la._lock_counter_and_alive_flag & life_assurance::alive_flag) 140 | { 141 | if (!_alive) 142 | unlock(); 143 | } 144 | 145 | ~execution_guard() 146 | { 147 | if (_alive) 148 | unlock(); 149 | } 150 | 151 | execution_guard(const execution_guard&) = delete; 152 | execution_guard& operator = (const execution_guard&) = delete; 153 | 154 | life_assurance::int_type is_alive() const WIGWAG_NOEXCEPT 155 | { return _alive; } 156 | 157 | private: 158 | void unlock() 159 | { 160 | life_assurance::int_type i = --_la->_lock_counter_and_alive_flag; 161 | if (i == 0) 162 | { 163 | WIGWAG_ANNOTATE_HAPPENS_AFTER(&_la->_lock_counter_and_alive_flag); 164 | WIGWAG_ANNOTATE_RELEASE(&_la->_lock_counter_and_alive_flag); 165 | 166 | std::unique_lock l(_sd._mutex); 167 | _sd._cond_var.notify_all(); 168 | } 169 | else 170 | WIGWAG_ANNOTATE_HAPPENS_BEFORE(&_la->_lock_counter_and_alive_flag); 171 | } 172 | }; 173 | }; 174 | 175 | #include 176 | 177 | }} 178 | 179 | #endif 180 | -------------------------------------------------------------------------------- /include/wigwag/policies/life_assurance/none.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_POLICIES_LIFE_ASSURANCE_NONE_HPP 2 | #define WIGWAG_POLICIES_LIFE_ASSURANCE_NONE_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | #include 16 | 17 | 18 | namespace wigwag { 19 | namespace life_assurance 20 | { 21 | 22 | #include 23 | 24 | struct none 25 | { 26 | using tag = life_assurance::tag>; 27 | 28 | class shared_data 29 | { }; 30 | 31 | struct life_assurance 32 | { 33 | void release_life_assurance(const shared_data&) 34 | { } 35 | 36 | bool node_should_be_released() const 37 | { return false; } 38 | 39 | bool release_node() const 40 | { return true; } 41 | }; 42 | 43 | struct life_checker 44 | { 45 | life_checker(const shared_data&, const life_assurance&) WIGWAG_NOEXCEPT { } 46 | }; 47 | 48 | struct execution_guard 49 | { 50 | execution_guard(const life_checker&) WIGWAG_NOEXCEPT { } 51 | execution_guard(const shared_data&, const life_assurance&) WIGWAG_NOEXCEPT { } 52 | int is_alive() const WIGWAG_NOEXCEPT { return true; } 53 | }; 54 | }; 55 | 56 | #include 57 | 58 | }} 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /include/wigwag/policies/life_assurance/policies.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_POLICIES_LIFE_ASSURANCE_POLICIES_HPP 2 | #define WIGWAG_POLICIES_LIFE_ASSURANCE_POLICIES_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | 19 | namespace wigwag { 20 | namespace life_assurance 21 | { 22 | 23 | using default_ = intrusive_life_tokens; 24 | 25 | }} 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /include/wigwag/policies/life_assurance/single_threaded.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_POLICIES_LIFE_ASSURANCE_SINGLE_THREADED_HPP 2 | #define WIGWAG_POLICIES_LIFE_ASSURANCE_SINGLE_THREADED_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | 19 | namespace wigwag { 20 | namespace life_assurance 21 | { 22 | 23 | #include 24 | 25 | struct single_threaded 26 | { 27 | using tag = life_assurance::tag>; 28 | 29 | class life_checker; 30 | class execution_guard; 31 | 32 | class shared_data 33 | { }; 34 | 35 | struct life_assurance 36 | { 37 | friend class life_checker; 38 | friend class execution_guard; 39 | 40 | private: 41 | mutable bool _alive; 42 | mutable int _ref_count; 43 | 44 | public: 45 | life_assurance() 46 | : _alive(true), _ref_count(2) // One ref in signal, another in token 47 | { } 48 | 49 | virtual ~life_assurance() 50 | { } 51 | 52 | life_assurance(const life_assurance&) = delete; 53 | life_assurance& operator = (const life_assurance&) = delete; 54 | 55 | 56 | void add_ref() const 57 | { ++_ref_count; } 58 | 59 | void release() const 60 | { 61 | if (release_node()) 62 | delete this; 63 | } 64 | 65 | void release_life_assurance(const shared_data&) 66 | { _alive = false; } 67 | 68 | bool node_should_be_released() const 69 | { return _ref_count == 1; } 70 | 71 | bool release_node() const 72 | { return --_ref_count == 0; } 73 | }; 74 | 75 | class life_checker 76 | { 77 | friend class execution_guard; 78 | 79 | wigwag::detail::intrusive_ptr _la; 80 | 81 | public: 82 | life_checker(const shared_data&, const life_assurance& la) WIGWAG_NOEXCEPT 83 | : _la(&la) 84 | { la.add_ref(); } 85 | }; 86 | 87 | class execution_guard 88 | { 89 | wigwag::detail::intrusive_ptr _la; 90 | 91 | public: 92 | execution_guard(const life_checker& c) 93 | : _la(c._la) 94 | { } 95 | 96 | execution_guard(const shared_data&, const life_assurance& la) 97 | : _la(&la) 98 | { la.add_ref(); } 99 | 100 | ~execution_guard() 101 | { } 102 | 103 | int is_alive() const WIGWAG_NOEXCEPT 104 | { return _la->_alive; } 105 | }; 106 | }; 107 | 108 | #include 109 | 110 | }} 111 | 112 | #endif 113 | -------------------------------------------------------------------------------- /include/wigwag/policies/life_assurance/tag.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_POLICIES_LIFE_ASSURANCE_TAG_HPP 2 | #define WIGWAG_POLICIES_LIFE_ASSURANCE_TAG_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | 16 | 17 | namespace wigwag { 18 | namespace life_assurance 19 | { 20 | 21 | template < typename Version_ > 22 | struct tag 23 | { using version = Version_; }; 24 | 25 | }} 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /include/wigwag/policies/ref_counter/atomic.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_POLICIES_REF_COUNTER_ATOMIC_HPP 2 | #define WIGWAG_POLICIES_REF_COUNTER_ATOMIC_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | #include 16 | 17 | #include 18 | 19 | 20 | namespace wigwag { 21 | namespace ref_counter 22 | { 23 | 24 | #include 25 | 26 | class atomic 27 | { 28 | public: 29 | using tag = ref_counter::tag>; 30 | 31 | private: 32 | mutable std::atomic _counter; 33 | 34 | public: 35 | atomic(int initVal) 36 | : _counter(initVal) 37 | { } 38 | 39 | int add_ref() const 40 | { return ++_counter; } 41 | 42 | int release() const 43 | { 44 | auto res = --_counter; 45 | if (res == 0) 46 | { 47 | WIGWAG_ANNOTATE_HAPPENS_AFTER(this); 48 | WIGWAG_ANNOTATE_RELEASE(this); 49 | } 50 | else 51 | WIGWAG_ANNOTATE_HAPPENS_BEFORE(this); 52 | return res; 53 | } 54 | }; 55 | 56 | #include 57 | 58 | }} 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /include/wigwag/policies/ref_counter/policies.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_POLICIES_REF_COUNTER_POLICIES_HPP 2 | #define WIGWAG_POLICIES_REF_COUNTER_POLICIES_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | #include 16 | 17 | 18 | namespace wigwag { 19 | namespace ref_counter 20 | { 21 | 22 | using default_ = atomic; 23 | 24 | }} 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /include/wigwag/policies/ref_counter/single_threaded.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_POLICIES_REF_COUNTER_SINGLE_THREADED_HPP 2 | #define WIGWAG_POLICIES_REF_COUNTER_SINGLE_THREADED_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | 16 | 17 | namespace wigwag { 18 | namespace ref_counter 19 | { 20 | 21 | #include 22 | 23 | class single_threaded 24 | { 25 | public: 26 | using tag = ref_counter::tag>; 27 | 28 | private: 29 | mutable int _counter; 30 | 31 | public: 32 | single_threaded(int initVal) 33 | : _counter(initVal) 34 | { } 35 | 36 | int add_ref() const 37 | { return ++_counter; } 38 | 39 | int release() const 40 | { return --_counter; } 41 | }; 42 | 43 | #include 44 | 45 | }} 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /include/wigwag/policies/ref_counter/tag.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_POLICIES_REF_COUNTER_TAG_HPP 2 | #define WIGWAG_POLICIES_REF_COUNTER_TAG_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | 16 | 17 | namespace wigwag { 18 | namespace ref_counter 19 | { 20 | 21 | template < typename Version_ > 22 | struct tag 23 | { using version = Version_; }; 24 | 25 | }} 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /include/wigwag/policies/state_populating/none.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_POLICIES_STATE_POPULATING_NONE_HPP 2 | #define WIGWAG_POLICIES_STATE_POPULATING_NONE_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | #include 16 | 17 | 18 | namespace wigwag { 19 | namespace state_populating 20 | { 21 | 22 | #include 23 | 24 | struct none 25 | { 26 | using tag = state_populating::tag>; 27 | 28 | template < typename HandlerType_ > 29 | struct handler_processor 30 | { 31 | bool has_populate_state() const WIGWAG_NOEXCEPT { return false; } 32 | void populate_state(const HandlerType_&) const WIGWAG_NOEXCEPT { } 33 | 34 | bool has_withdraw_state() const WIGWAG_NOEXCEPT { return false; } 35 | void withdraw_state(const HandlerType_&) const WIGWAG_NOEXCEPT { } 36 | }; 37 | }; 38 | 39 | #include 40 | 41 | }} 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /include/wigwag/policies/state_populating/policies.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_POLICIES_STATE_POPULATING_POLICIES_HPP 2 | #define WIGWAG_POLICIES_STATE_POPULATING_POLICIES_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | namespace wigwag { 18 | namespace state_populating 19 | { 20 | 21 | using default_ = populator_only; 22 | 23 | }} 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /include/wigwag/policies/state_populating/populator_and_withdrawer.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_POLICIES_STATE_POPULATING_POPULATOR_AND_WITHDRAWER_HPP 2 | #define WIGWAG_POLICIES_STATE_POPULATING_POPULATOR_AND_WITHDRAWER_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | #include 16 | 17 | #include 18 | #include 19 | 20 | 21 | namespace wigwag { 22 | namespace state_populating 23 | { 24 | 25 | #include 26 | 27 | struct populator_and_withdrawer 28 | { 29 | using tag = state_populating::tag>; 30 | 31 | template < typename HandlerType_ > 32 | class handler_processor 33 | { 34 | WIGWAG_PRIVATE_IS_CONSTRUCTIBLE_WORKAROUND: 35 | using handler_processor_func = std::function; 36 | 37 | private: 38 | handler_processor_func _populator; 39 | handler_processor_func _withdrawer; 40 | 41 | public: 42 | handler_processor(handler_processor_func populator = handler_processor_func(), handler_processor_func withdrawer = handler_processor_func()) 43 | : _populator(populator), _withdrawer(withdrawer) 44 | { } 45 | 46 | template < typename K_, typename V_ > 47 | handler_processor(const std::pair& populator_and_withdrawer_pair, typename std::enable_if::value && std::is_constructible::value, wigwag::detail::enabler>::type = wigwag::detail::enabler()) 48 | : _populator(populator_and_withdrawer_pair.first), _withdrawer(populator_and_withdrawer_pair.second) 49 | { } 50 | 51 | bool has_populate_state() const WIGWAG_NOEXCEPT { return (bool)_populator; } 52 | void populate_state(const HandlerType_& handler) const { _populator(handler); } 53 | 54 | bool has_withdraw_state() const WIGWAG_NOEXCEPT { return (bool)_withdrawer; } 55 | void withdraw_state(const HandlerType_& handler) const { _withdrawer(handler); } 56 | }; 57 | }; 58 | 59 | #include 60 | 61 | }} 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /include/wigwag/policies/state_populating/populator_only.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_POLICIES_STATE_POPULATING_POPULATOR_ONLY_HPP 2 | #define WIGWAG_POLICIES_STATE_POPULATING_POPULATOR_ONLY_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | #include 16 | 17 | #include 18 | 19 | 20 | namespace wigwag { 21 | namespace state_populating 22 | { 23 | 24 | #include 25 | 26 | struct populator_only 27 | { 28 | using tag = state_populating::tag>; 29 | 30 | template < typename HandlerType_ > 31 | class handler_processor 32 | { 33 | using handler_processor_func = std::function; 34 | 35 | private: 36 | handler_processor_func _populator; 37 | 38 | public: 39 | handler_processor(handler_processor_func populator = handler_processor_func()) 40 | : _populator(populator) 41 | { } 42 | 43 | bool has_populate_state() const WIGWAG_NOEXCEPT { return (bool)_populator; } 44 | void populate_state(const HandlerType_& handler) const { _populator(handler); } 45 | 46 | bool has_withdraw_state() const WIGWAG_NOEXCEPT { return false; } 47 | void withdraw_state(const HandlerType_&) const WIGWAG_NOEXCEPT { } 48 | }; 49 | }; 50 | 51 | #include 52 | 53 | }} 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /include/wigwag/policies/state_populating/tag.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_POLICIES_STATE_POPULATING_TAG_HPP 2 | #define WIGWAG_POLICIES_STATE_POPULATING_TAG_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | 16 | 17 | namespace wigwag { 18 | namespace state_populating 19 | { 20 | 21 | template < typename Version_ > 22 | struct tag 23 | { using version = Version_; }; 24 | 25 | }} 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /include/wigwag/policies/threading/none.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_POLICIES_THREADING_NONE_HPP 2 | #define WIGWAG_POLICIES_THREADING_NONE_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | #include 16 | 17 | 18 | namespace wigwag { 19 | namespace threading 20 | { 21 | 22 | #include 23 | 24 | struct none 25 | { 26 | using tag = threading::tag>; 27 | 28 | class lock_primitive 29 | { 30 | public: 31 | void get_primitive() const WIGWAG_NOEXCEPT { } 32 | 33 | void lock_nonrecursive() const WIGWAG_NOEXCEPT { } 34 | void unlock_nonrecursive() const WIGWAG_NOEXCEPT { } 35 | 36 | void lock_recursive() const WIGWAG_NOEXCEPT { } 37 | void unlock_recursive() const WIGWAG_NOEXCEPT { } 38 | }; 39 | }; 40 | 41 | #include 42 | 43 | }} 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /include/wigwag/policies/threading/own_mutex.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_POLICIES_THREADING_OWN_MUTEX_HPP 2 | #define WIGWAG_POLICIES_THREADING_OWN_MUTEX_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | #include 16 | 17 | #include 18 | 19 | 20 | namespace wigwag { 21 | namespace threading 22 | { 23 | 24 | #include 25 | 26 | struct own_mutex 27 | { 28 | using tag = threading::tag>; 29 | 30 | class lock_primitive 31 | { 32 | private: 33 | mutable std::mutex _mutex; 34 | 35 | public: 36 | std::mutex& get_primitive() const WIGWAG_NOEXCEPT { return _mutex; } 37 | 38 | void lock_nonrecursive() const { _mutex.lock(); } 39 | void unlock_nonrecursive() const { _mutex.unlock(); } 40 | 41 | void lock_recursive() const WIGWAG_NOEXCEPT { } 42 | void unlock_recursive() const WIGWAG_NOEXCEPT { } 43 | }; 44 | }; 45 | 46 | #include 47 | 48 | }} 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /include/wigwag/policies/threading/own_recursive_mutex.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_POLICIES_THREADING_OWN_RECURSIVE_MUTEX_HPP 2 | #define WIGWAG_POLICIES_THREADING_OWN_RECURSIVE_MUTEX_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | #include 16 | 17 | #include 18 | 19 | 20 | namespace wigwag { 21 | namespace threading 22 | { 23 | 24 | #include 25 | 26 | struct own_recursive_mutex 27 | { 28 | using tag = threading::tag>; 29 | 30 | class lock_primitive 31 | { 32 | private: 33 | mutable std::recursive_mutex _mutex; 34 | 35 | public: 36 | std::recursive_mutex& get_primitive() const WIGWAG_NOEXCEPT { return _mutex; } 37 | 38 | void lock_nonrecursive() const { _mutex.lock(); } 39 | void unlock_nonrecursive() const { _mutex.unlock(); } 40 | 41 | void lock_recursive() const { _mutex.lock(); } 42 | void unlock_recursive() const { _mutex.unlock(); } 43 | }; 44 | }; 45 | 46 | #include 47 | 48 | }} 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /include/wigwag/policies/threading/policies.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_POLICIES_THREADING_POLICIES_HPP 2 | #define WIGWAG_POLICIES_THREADING_POLICIES_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | namespace wigwag { 21 | namespace threading 22 | { 23 | 24 | using default_ = own_recursive_mutex; 25 | 26 | }} 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /include/wigwag/policies/threading/shared_mutex.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_POLICIES_THREADING_SHARED_MUTEX_HPP 2 | #define WIGWAG_POLICIES_THREADING_SHARED_MUTEX_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | #include 16 | 17 | #include 18 | #include 19 | 20 | 21 | namespace wigwag { 22 | namespace threading 23 | { 24 | 25 | #include 26 | 27 | struct shared_mutex 28 | { 29 | using tag = threading::tag>; 30 | 31 | class lock_primitive 32 | { 33 | private: 34 | std::shared_ptr _mutex; 35 | 36 | public: 37 | lock_primitive(const std::shared_ptr mutex) 38 | : _mutex(mutex) 39 | { } 40 | 41 | const std::shared_ptr& get_primitive() const WIGWAG_NOEXCEPT { return _mutex; } 42 | 43 | void lock_nonrecursive() const { _mutex->lock(); } 44 | void unlock_nonrecursive() const { _mutex->unlock(); } 45 | 46 | void lock_recursive() const WIGWAG_NOEXCEPT { } 47 | void unlock_recursive() const WIGWAG_NOEXCEPT { } 48 | }; 49 | }; 50 | 51 | #include 52 | 53 | }} 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /include/wigwag/policies/threading/shared_recursive_mutex.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_POLICIES_THREADING_SHARED_RECURSIVE_MUTEX_HPP 2 | #define WIGWAG_POLICIES_THREADING_SHARED_RECURSIVE_MUTEX_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | #include 16 | 17 | #include 18 | #include 19 | 20 | 21 | namespace wigwag { 22 | namespace threading 23 | { 24 | 25 | #include 26 | 27 | struct shared_recursive_mutex 28 | { 29 | using tag = threading::tag>; 30 | 31 | class lock_primitive 32 | { 33 | private: 34 | std::shared_ptr _mutex; 35 | 36 | public: 37 | lock_primitive(std::shared_ptr mutex) 38 | : _mutex(std::move(mutex)) 39 | { } 40 | 41 | const std::shared_ptr& get_primitive() const WIGWAG_NOEXCEPT { return _mutex; } 42 | 43 | void lock_nonrecursive() const { _mutex->lock(); } 44 | void unlock_nonrecursive() const { _mutex->unlock(); } 45 | 46 | void lock_recursive() const { _mutex->lock(); } 47 | void unlock_recursive() const { _mutex->unlock(); } 48 | }; 49 | }; 50 | 51 | #include 52 | 53 | }} 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /include/wigwag/policies/threading/tag.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_POLICIES_THREADING_TAG_HPP 2 | #define WIGWAG_POLICIES_THREADING_TAG_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | 16 | 17 | namespace wigwag { 18 | namespace threading 19 | { 20 | 21 | template < typename Version_ > 22 | struct tag 23 | { using version = Version_; }; 24 | 25 | }} 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /include/wigwag/signal.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_SIGNAL_HPP 2 | #define WIGWAG_SIGNAL_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | 22 | namespace wigwag 23 | { 24 | 25 | #include 26 | 27 | namespace detail 28 | { 29 | using signal_policies_config = policies_config< 30 | policies_config_entry, 31 | policies_config_entry, 32 | policies_config_entry, 33 | policies_config_entry, 34 | policies_config_entry, 35 | policies_config_entry 36 | >; 37 | 38 | template < typename T_ > 39 | struct signature_getter 40 | { using type = T_; }; 41 | } 42 | 43 | 44 | template < 45 | typename Signature_, 46 | typename... Policies_ 47 | > 48 | class signal; 49 | 50 | template < 51 | typename... ArgTypes_, 52 | typename... Policies_ 53 | > 54 | class signal 55 | { 56 | public: 57 | using signature = typename detail::signature_getter::type; 58 | 59 | private: 60 | template < template class PolicyConcept_ > 61 | using policy = typename detail::policy_picker::type; 62 | 63 | using exception_handling_policy = policy; 64 | using threading_policy = policy; 65 | using state_populating_policy = policy; 66 | using life_assurance_policy = policy; 67 | using creation_policy = policy; 68 | using ref_counter_policy = policy; 69 | 70 | public: 71 | using handler_type = std::function; 72 | 73 | WIGWAG_PRIVATE_IS_CONSTRUCTIBLE_WORKAROUND: 74 | using impl_type = detail::signal_impl; 75 | using impl_type_with_attr = detail::signal_with_attributes_impl; 76 | 77 | private: 78 | using impl_type_ptr = detail::intrusive_ptr; 79 | 80 | using storage = typename creation_policy::template storage; 81 | 82 | private: 83 | detail::creation_storage_adapter _impl; 84 | 85 | public: 86 | template < typename... Args_, bool E_ = std::is_constructible::value, typename = typename std::enable_if::type > 87 | signal(signal_attributes attributes, Args_&&... args) 88 | { 89 | if (attributes == signal_attributes::none) 90 | _impl.template create(std::forward(args)...); 91 | else 92 | _impl.template create(attributes, std::forward(args)...); 93 | } 94 | 95 | template < typename... Args_, bool E_ = std::is_constructible::value, typename = typename std::enable_if::type > 96 | signal(Args_&&... args) 97 | { _impl.template create(std::forward(args)...); } 98 | 99 | ~signal() 100 | { 101 | if (_impl) 102 | { 103 | _impl->get_lock_primitive().lock_nonrecursive(); 104 | auto sg = detail::at_scope_exit([&] { _impl->get_lock_primitive().unlock_nonrecursive(); } ); 105 | 106 | _impl->finalize_nodes(); 107 | } 108 | } 109 | 110 | signal(const signal&) = delete; 111 | signal& operator = (const signal&) = delete; 112 | 113 | auto lock_primitive() const -> decltype(_impl->get_lock_primitive().get_primitive()) 114 | { return _impl->get_lock_primitive().get_primitive(); } 115 | 116 | signal_connector connector() const 117 | { return signal_connector(_impl.get_ptr()); } 118 | 119 | template < typename HandlerFunc_ > 120 | token connect(HandlerFunc_ handler, handler_attributes attributes = handler_attributes::none) const 121 | { return _impl->connect(std::move(handler), attributes); } 122 | 123 | template < typename HandlerFunc_ > 124 | token connect(std::shared_ptr worker, HandlerFunc_ handler, handler_attributes attributes = handler_attributes::none) const 125 | { return _impl->connect(std::move(worker), std::move(handler), attributes); } 126 | 127 | void operator() (ArgTypes_... args) const 128 | { 129 | if (_impl) 130 | _impl->invoke(args...); 131 | } 132 | }; 133 | 134 | #include 135 | 136 | } 137 | 138 | #endif 139 | -------------------------------------------------------------------------------- /include/wigwag/signal_attributes.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_SIGNAL_ATTRIBUTES_HPP 2 | #define WIGWAG_SIGNAL_ATTRIBUTES_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | 16 | 17 | namespace wigwag 18 | { 19 | 20 | #include 21 | 22 | enum class signal_attributes 23 | { 24 | none = 0x0, 25 | connect_sync_only = 0x1, 26 | connect_async_only = 0x2 27 | }; 28 | 29 | WIGWAG_DECLARE_ENUM_BITWISE_OPERATORS(signal_attributes) 30 | 31 | #include 32 | 33 | } 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /include/wigwag/signal_connector.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_SIGNAL_CONNECTOR_HPP 2 | #define WIGWAG_SIGNAL_CONNECTOR_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | 19 | namespace wigwag 20 | { 21 | 22 | #include 23 | 24 | template < typename Signature_ > 25 | class signal_connector 26 | { 27 | public: 28 | using handler_type = std::function; 29 | 30 | private: 31 | using impl_type = detail::signal_connector_impl; 32 | using impl_type_ptr = detail::intrusive_ptr; 33 | 34 | private: 35 | impl_type_ptr _impl; 36 | 37 | public: 38 | explicit signal_connector(impl_type_ptr impl) 39 | : _impl(std::move(impl)) 40 | { } 41 | 42 | template < typename HandlerFunc_ > 43 | token connect(HandlerFunc_ handler, handler_attributes attributes = handler_attributes::none) const 44 | { return _impl->connect(std::move(handler), attributes); } 45 | 46 | template < typename HandlerFunc_ > 47 | token connect(std::shared_ptr worker, HandlerFunc_ handler, handler_attributes attributes = handler_attributes::none) const 48 | { return _impl->connect(std::move(worker), std::move(handler), attributes); } 49 | }; 50 | 51 | #include 52 | 53 | } 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /include/wigwag/task_executor.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_TASK_EXECUTOR_HPP 2 | #define WIGWAG_TASK_EXECUTOR_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | 16 | 17 | namespace wigwag 18 | { 19 | 20 | #include 21 | 22 | struct task_executor 23 | { 24 | virtual ~task_executor() { } 25 | 26 | virtual void add_task(std::function task) = 0; 27 | }; 28 | 29 | #include 30 | 31 | } 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /include/wigwag/thread_task_executor.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_THREAD_TASK_EXECUTOR_HPP 2 | #define WIGWAG_THREAD_TASK_EXECUTOR_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include 20 | #include 21 | 22 | 23 | namespace wigwag 24 | { 25 | 26 | #include 27 | 28 | namespace detail 29 | { 30 | using thread_task_executor_policies_config = policies_config< 31 | policies_config_entry 32 | >; 33 | } 34 | 35 | 36 | template < typename... Policies_ > 37 | class basic_thread_task_executor : 38 | public task_executor, 39 | private detail::policy_picker::type 40 | { 41 | using exception_handling_policy = typename detail::policy_picker::type; 42 | 43 | using task_queue = std::queue>; 44 | 45 | private: 46 | task_queue _tasks; 47 | bool _alive; 48 | std::mutex _mutex; 49 | std::condition_variable _cv; 50 | std::thread _thread; 51 | 52 | public: 53 | template < typename... Args_ > 54 | basic_thread_task_executor(Args_&... args) 55 | : exception_handling_policy(std::forward(args)...), _alive(true) 56 | { _thread = std::thread(&basic_thread_task_executor::thread_func, this); } 57 | 58 | ~basic_thread_task_executor() 59 | { 60 | { 61 | std::lock_guard l(_mutex); 62 | _alive = false; 63 | _cv.notify_all(); 64 | } 65 | if (_thread.joinable()) 66 | _thread.join(); 67 | } 68 | 69 | virtual void add_task(std::function task) 70 | { 71 | std::lock_guard l(_mutex); 72 | bool need_wakeup = _tasks.empty(); 73 | _tasks.push(std::move(task)); 74 | if (need_wakeup) 75 | _cv.notify_all(); 76 | } 77 | 78 | private: 79 | void thread_func() 80 | { 81 | std::unique_lock l(_mutex); 82 | while (_alive || !_tasks.empty()) 83 | { 84 | if (_tasks.empty()) 85 | { 86 | _cv.wait(l); 87 | continue; 88 | } 89 | 90 | exception_handling_policy::handle_exceptions([&]() { 91 | std::function task; 92 | std::swap(_tasks.front(), task); 93 | _tasks.pop(); 94 | 95 | l.unlock(); 96 | auto sg = detail::at_scope_exit([&] { l.lock(); } ); 97 | 98 | task(); 99 | } ); 100 | } 101 | } 102 | }; 103 | 104 | 105 | using thread_task_executor = basic_thread_task_executor<>; 106 | 107 | 108 | #include 109 | 110 | } 111 | 112 | #endif 113 | -------------------------------------------------------------------------------- /include/wigwag/threadless_task_executor.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_THREADLESS_TASK_EXECUTOR_HPP 2 | #define WIGWAG_THREADLESS_TASK_EXECUTOR_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include 20 | #include 21 | 22 | 23 | namespace wigwag 24 | { 25 | 26 | #include 27 | 28 | namespace detail 29 | { 30 | using threadless_task_executor_policies_config = policies_config< 31 | policies_config_entry, 32 | policies_config_entry 33 | >; 34 | } 35 | 36 | 37 | template < typename... Policies_ > 38 | class basic_threadless_task_executor : 39 | public task_executor, 40 | private detail::policy_picker::type 41 | { 42 | template < template class PolicyConcept_ > 43 | using policy = typename detail::policy_picker::type; 44 | 45 | using exception_handling_policy = policy; 46 | using threading_policy = policy; 47 | 48 | using task_queue = std::queue>; 49 | 50 | using lock_primitive = typename threading_policy::lock_primitive; 51 | 52 | private: 53 | task_queue _tasks; 54 | lock_primitive _lp; 55 | 56 | public: 57 | template < typename... Args_ > 58 | basic_threadless_task_executor(Args_&... args) 59 | : exception_handling_policy(std::forward(args)...) 60 | { } 61 | 62 | ~basic_threadless_task_executor() 63 | { } 64 | 65 | virtual void add_task(std::function task) 66 | { 67 | _lp.lock_nonrecursive(); 68 | auto sg = detail::at_scope_exit([&] { _lp.unlock_nonrecursive(); } ); 69 | 70 | _tasks.push(std::move(task)); 71 | } 72 | 73 | void process_tasks() 74 | { 75 | _lp.lock_nonrecursive(); 76 | auto sg = detail::at_scope_exit([&] { _lp.unlock_nonrecursive(); } ); 77 | 78 | while (!_tasks.empty()) 79 | { 80 | exception_handling_policy::handle_exceptions([&]() { 81 | std::function task; 82 | std::swap(_tasks.front(), task); 83 | _tasks.pop(); 84 | 85 | _lp.unlock_nonrecursive(); 86 | auto sg = detail::at_scope_exit([&] { _lp.lock_nonrecursive(); } ); 87 | 88 | task(); 89 | } ); 90 | } 91 | } 92 | }; 93 | 94 | 95 | using threadless_task_executor = basic_threadless_task_executor<>; 96 | 97 | 98 | #include 99 | 100 | } 101 | 102 | #endif 103 | -------------------------------------------------------------------------------- /include/wigwag/token.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_TOKEN_HPP 2 | #define WIGWAG_TOKEN_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | 16 | 17 | namespace wigwag 18 | { 19 | 20 | #include 21 | 22 | class token 23 | { 24 | public: 25 | struct implementation 26 | { 27 | virtual void release_token_impl() = 0; 28 | virtual ~implementation() { } 29 | }; 30 | 31 | private: 32 | implementation* _impl; 33 | 34 | private: 35 | token(implementation* impl) 36 | : _impl(impl) 37 | { } 38 | 39 | public: 40 | token() 41 | : _impl(nullptr) 42 | { } 43 | 44 | token(token&& other) 45 | : _impl(other._impl) 46 | { other._impl = nullptr; } 47 | 48 | ~token() 49 | { reset(); } 50 | 51 | token(const token&) = delete; 52 | token& operator = (const token&) = delete; 53 | 54 | token& operator = (token&& other) 55 | { 56 | reset(); 57 | 58 | _impl = other._impl; 59 | other._impl = nullptr; 60 | 61 | return *this; 62 | } 63 | 64 | void reset() 65 | { 66 | if (!_impl) 67 | return; 68 | 69 | _impl->release_token_impl(); 70 | _impl = nullptr; 71 | } 72 | 73 | template < typename Implementation_, typename... Args_ > 74 | static token create(Args_&&... args) 75 | { return token(new Implementation_(std::forward(args)...)); } 76 | }; 77 | 78 | #include 79 | 80 | } 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /include/wigwag/token_pool.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WIGWAG_TOKEN_POOL_HPP 2 | #define WIGWAG_TOKEN_POOL_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | 16 | #include 17 | #include 18 | 19 | 20 | namespace wigwag 21 | { 22 | 23 | #include 24 | 25 | class token_pool 26 | { 27 | using tokens_container = std::vector; 28 | 29 | private: 30 | tokens_container _tokens; 31 | mutable std::mutex _mutex; 32 | 33 | public: 34 | token_pool& operator += (token&& t) 35 | { 36 | add_token(std::move(t)); 37 | return *this; 38 | } 39 | 40 | void add_token(token&& t) 41 | { 42 | std::lock_guard l(_mutex); 43 | _tokens.push_back(std::move(t)); 44 | } 45 | 46 | void release() 47 | { 48 | std::lock_guard l(_mutex); 49 | _tokens.clear(); 50 | } 51 | }; 52 | 53 | #include 54 | 55 | } 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /src/benchmarks/FunctionBenchmarks.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BENCHMARKS_FUNCTIONSBENCHMARKS_HPP 2 | #define BENCHMARKS_FUNCTIONSBENCHMARKS_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | #include 16 | 17 | 18 | namespace benchmarks 19 | { 20 | 21 | template < typename FunctionDesc_ > 22 | class FunctionBenchmarks : public BenchmarksClass 23 | { 24 | using FunctionType = typename FunctionDesc_::FunctionType; 25 | 26 | public: 27 | FunctionBenchmarks() 28 | : BenchmarksClass("function") 29 | { 30 | AddBenchmark<>("basic", &FunctionBenchmarks::Basic); 31 | } 32 | 33 | private: 34 | static void Basic(BenchmarkContext& context) 35 | { 36 | const auto n = context.GetIterationsCount(); 37 | 38 | StorageArray f(n); 39 | 40 | context.Profile("create", n, [&]{ f.Construct([]{ return []{}; }); }); 41 | context.MeasureMemory("function", n); 42 | context.Profile("invoke", n, [&]{ f.ForEach([](const FunctionType& f){ f(); }); }); 43 | context.Profile("destroy", n, [&]{ f.Destruct(); }); 44 | } 45 | }; 46 | 47 | } 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /src/benchmarks/GenericBenchmarks.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BENCHMARKS_GENERICBENCHMARKS_HPP 2 | #define BENCHMARKS_GENERICBENCHMARKS_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | #include 16 | 17 | 18 | namespace benchmarks 19 | { 20 | 21 | template < typename Desc_ > 22 | class GenericBenchmarks : public BenchmarksClass 23 | { 24 | using Type = typename Desc_::Type; 25 | 26 | public: 27 | GenericBenchmarks() 28 | : BenchmarksClass("generic") 29 | { 30 | AddBenchmark<>("create", &GenericBenchmarks::Create); 31 | } 32 | 33 | private: 34 | static void Create(BenchmarkContext& context) 35 | { 36 | const auto n = context.GetIterationsCount(); 37 | 38 | StorageArray m(n); 39 | 40 | context.Profile("create", n, [&]{ m.Construct(); }); 41 | context.MeasureMemory("object", n); 42 | context.Profile("destroy", n, [&]{ m.Destruct(); }); 43 | } 44 | }; 45 | 46 | } 47 | 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /src/benchmarks/MutexBenchmarks.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BENCHMARKS_MUTEXBENCHMARKS_HPP 2 | #define BENCHMARKS_MUTEXBENCHMARKS_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | #include 16 | 17 | 18 | namespace benchmarks 19 | { 20 | 21 | template < typename MutexDesc_ > 22 | class MutexBenchmarks : public BenchmarksClass 23 | { 24 | using MutexType = typename MutexDesc_::MutexType; 25 | 26 | public: 27 | MutexBenchmarks() 28 | : BenchmarksClass("mutex") 29 | { 30 | AddBenchmark<>("basic", &MutexBenchmarks::Basic); 31 | } 32 | 33 | private: 34 | static void Basic(BenchmarkContext& context) 35 | { 36 | const auto n = context.GetIterationsCount(); 37 | 38 | StorageArray m(n); 39 | 40 | context.Profile("create", n, [&]{ m.Construct(); }); 41 | context.MeasureMemory("mutex", n); 42 | context.Profile("lock", n, [&]{ m.ForEach([](MutexType& m){ m.lock(); }); }); 43 | context.Profile("unlock", n, [&]{ m.ForEach([](MutexType& m){ m.unlock(); }); }); 44 | context.Profile("destroy", n, [&]{ m.Destruct(); }); 45 | } 46 | }; 47 | 48 | } 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /src/benchmarks/SignalBenchmarks.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SRC_BENCHMARKS_SIGNALSBENCHMARKS_HPP 2 | #define SRC_BENCHMARKS_SIGNALSBENCHMARKS_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | #include 16 | 17 | 18 | namespace benchmarks 19 | { 20 | 21 | template < typename SignalsDesc_ > 22 | class SignalBenchmarks : public BenchmarksClass 23 | { 24 | using SignalType = typename SignalsDesc_::SignalType; 25 | using HandlerType = typename SignalsDesc_::HandlerType; 26 | using ConnectionType = typename SignalsDesc_::ConnectionType; 27 | 28 | public: 29 | SignalBenchmarks() 30 | : BenchmarksClass("signal") 31 | { 32 | AddBenchmark<>("createEmpty", &SignalBenchmarks::CreateEmpty); 33 | AddBenchmark<>("create", &SignalBenchmarks::Create); 34 | AddBenchmark<>("handlerSize", &SignalBenchmarks::HandlerSize); 35 | AddBenchmark("invoke", &SignalBenchmarks::Invoke, {"numSlots"}); 36 | AddBenchmark("connect", &SignalBenchmarks::Connect, {"numSlots"}); 37 | } 38 | 39 | private: 40 | static void CreateEmpty(BenchmarkContext& context) 41 | { 42 | const auto n = context.GetIterationsCount(); 43 | 44 | StorageArray s(n); 45 | 46 | context.Profile("create", n, [&]{ s.Construct(); }); 47 | context.MeasureMemory("signal", n); 48 | context.Profile("destroy", n, [&]{ s.Destruct(); }); 49 | } 50 | 51 | static void Create(BenchmarkContext& context) 52 | { 53 | const auto n = context.GetIterationsCount(); 54 | 55 | StorageArray s(n); 56 | 57 | s.Construct(); 58 | s.ForEach([](SignalType& s){ ConnectionType(s.connect(SignalsDesc_::MakeHandler())); s(); }); 59 | context.MeasureMemory("signal", n); 60 | context.Profile("destroy", n, [&]{ s.Destruct(); }); 61 | } 62 | 63 | static void HandlerSize(BenchmarkContext& context) 64 | { 65 | HandlerType handler = SignalsDesc_::MakeHandler(); 66 | SignalType s; 67 | StorageArray c(context.GetIterationsCount()); 68 | 69 | c.Construct([&]{ return s.connect(handler); }); 70 | context.MeasureMemory("handler", context.GetIterationsCount()); 71 | context.Profile("disconnect", context.GetIterationsCount(), [&]{ c.Destruct(); }); 72 | } 73 | 74 | static void Invoke(BenchmarkContext& context, int64_t numSlots) 75 | { 76 | const auto n = context.GetIterationsCount(); 77 | 78 | HandlerType handler = SignalsDesc_::MakeHandler(); 79 | SignalType s; 80 | StorageArray c(numSlots); 81 | 82 | c.Construct([&]{ return s.connect(handler); }); 83 | 84 | { 85 | auto op = context.Profile("invoke", numSlots * n); 86 | for (int64_t i = 0; i < n; ++i) 87 | s(); 88 | } 89 | 90 | c.Destruct(); 91 | } 92 | 93 | static void Connect(BenchmarkContext& context, int64_t numSlots) 94 | { 95 | const auto n = context.GetIterationsCount(); 96 | 97 | HandlerType handler = SignalsDesc_::MakeHandler(); 98 | std::vector s(n); 99 | StorageArray c(numSlots * n); 100 | 101 | { 102 | auto op = context.Profile("connect", numSlots * n); 103 | for (int64_t j = 0; j < n; ++j) 104 | for (int64_t i = 0; i < numSlots; ++i) 105 | c[i + j * numSlots].Construct(s[j].connect(handler)); 106 | } 107 | 108 | context.Profile("disconnect", numSlots * n, [&]{ c.Destruct(); }); 109 | } 110 | }; 111 | 112 | } 113 | 114 | #endif 115 | -------------------------------------------------------------------------------- /src/benchmarks/descriptors/function/boost.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BENCHMARKS_DESCRIPTORS_FUNCTIONS_BOOST_HPP 2 | #define BENCHMARKS_DESCRIPTORS_FUNCTIONS_BOOST_HPP 3 | 4 | 5 | #include 6 | 7 | #include 8 | 9 | 10 | namespace descriptors { 11 | namespace function { 12 | namespace boost 13 | { 14 | 15 | struct Regular 16 | { 17 | using FunctionType = ::boost::function; 18 | 19 | static std::string GetName() { return "boost"; } 20 | }; 21 | 22 | }}} 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /src/benchmarks/descriptors/function/std.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BENCHMARKS_DESCRIPTORS_FUNCTIONS_STD_HPP 2 | #define BENCHMARKS_DESCRIPTORS_FUNCTIONS_STD_HPP 3 | 4 | 5 | #include 6 | #include 7 | 8 | 9 | namespace descriptors { 10 | namespace function { 11 | namespace std 12 | { 13 | 14 | struct Regular 15 | { 16 | using FunctionType = ::std::function; 17 | 18 | static ::std::string GetName() { return "std"; } 19 | }; 20 | 21 | }}} 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /src/benchmarks/descriptors/generic/boost.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BENCHMARKS_DESCRIPTORS_GENERIC_BOOST_HPP 2 | #define BENCHMARKS_DESCRIPTORS_GENERIC_BOOST_HPP 3 | 4 | 5 | #include 6 | 7 | #include 8 | 9 | 10 | namespace descriptors { 11 | namespace generic { 12 | namespace boost 13 | { 14 | 15 | struct ConditionVariable 16 | { 17 | using Type = ::boost::condition_variable; 18 | static std::string GetName() { return "boost_condition_variable"; } 19 | }; 20 | 21 | 22 | }}} 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /src/benchmarks/descriptors/generic/std.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BENCHMARKS_DESCRIPTORS_GENERIC_STD_HPP 2 | #define BENCHMARKS_DESCRIPTORS_GENERIC_STD_HPP 3 | 4 | 5 | #include 6 | #include 7 | 8 | 9 | namespace descriptors { 10 | namespace generic { 11 | namespace std 12 | { 13 | 14 | struct ConditionVariable 15 | { 16 | using Type = ::std::condition_variable; 17 | static ::std::string GetName() { return "std_condition_variable"; } 18 | }; 19 | 20 | 21 | }}} 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /src/benchmarks/descriptors/generic/wigwag.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BENCHMARKS_DESCRIPTORS_GENERIC_WIGWAG_HPP 2 | #define BENCHMARKS_DESCRIPTORS_GENERIC_WIGWAG_HPP 3 | 4 | 5 | #include 6 | 7 | #include 8 | 9 | 10 | namespace descriptors { 11 | namespace generic { 12 | namespace wigwag 13 | { 14 | 15 | struct LifeToken 16 | { 17 | using Type = ::wigwag::life_token; 18 | static ::std::string GetName() { return "life_token"; } 19 | }; 20 | 21 | 22 | }}} 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /src/benchmarks/descriptors/mutex/boost.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BENCHMARKS_DESCRIPTORS_THREADING_BOOST_HPP 2 | #define BENCHMARKS_DESCRIPTORS_THREADING_BOOST_HPP 3 | 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | 12 | namespace descriptors { 13 | namespace mutex { 14 | namespace boost 15 | { 16 | 17 | struct Mutex 18 | { 19 | using MutexType = ::boost::mutex; 20 | static std::string GetName() { return "boost"; } 21 | }; 22 | 23 | struct RecursiveMutex 24 | { 25 | using MutexType = ::boost::recursive_mutex; 26 | static std::string GetName() { return "boost_recursive"; } 27 | }; 28 | 29 | 30 | }}} 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /src/benchmarks/descriptors/mutex/std.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BENCHMARKS_DESCRIPTORS_THREADING_STD_HPP 2 | #define BENCHMARKS_DESCRIPTORS_THREADING_STD_HPP 3 | 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | 10 | namespace descriptors { 11 | namespace mutex { 12 | namespace std 13 | { 14 | 15 | struct Mutex 16 | { 17 | using MutexType = ::std::mutex; 18 | static ::std::string GetName() { return "std"; } 19 | }; 20 | 21 | struct RecursiveMutex 22 | { 23 | using MutexType = ::std::recursive_mutex; 24 | static ::std::string GetName() { return "std_recursive"; } 25 | }; 26 | 27 | }}} 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /src/benchmarks/descriptors/signal/boost.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SRC_BENCHMARKS_DESCRIPTORS_SIGNALS_BOOST_HPP 2 | #define SRC_BENCHMARKS_DESCRIPTORS_SIGNALS_BOOST_HPP 3 | 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | 10 | namespace descriptors { 11 | namespace signal { 12 | namespace boost 13 | { 14 | using namespace ::boost; 15 | 16 | 17 | template < typename Signature_, typename TrackablePtr_ > 18 | class TrackingSlotWrapper 19 | { 20 | using FuncType = std::function; 21 | using SlotType = signals2::slot; 22 | 23 | private: 24 | FuncType _f; 25 | TrackablePtr_ _t; 26 | 27 | public: 28 | TrackingSlotWrapper(const FuncType& f, const TrackablePtr_& t) 29 | : _f(f), _t(t) 30 | { } 31 | 32 | operator SlotType() const 33 | { 34 | SlotType result(_f); 35 | DoTrack(result, _t); 36 | return result; 37 | } 38 | 39 | private: 40 | template < typename Slot_, typename T_ > 41 | static void DoTrack(Slot_& s, const shared_ptr& t) 42 | { s.track(t); } 43 | 44 | template < typename Slot_, typename T_ > 45 | static void DoTrack(Slot_& s, const T_& t, int dummy = 0) 46 | { s.track_foreign(t); } 47 | }; 48 | 49 | 50 | struct Tracking 51 | { 52 | using SignalType = signals2::signal; 53 | using HandlerType = TrackingSlotWrapper>; 54 | using ConnectionType = signals2::scoped_connection; 55 | 56 | static HandlerType MakeHandler() { return HandlerType([]{}, make_shared()); } 57 | static std::string GetName() { return "boost_tracking"; } 58 | }; 59 | 60 | struct Regular 61 | { 62 | using SignalType = signals2::signal; 63 | using HandlerType = std::function; 64 | using ConnectionType = signals2::scoped_connection; 65 | 66 | static HandlerType MakeHandler() { return []{}; } 67 | static std::string GetName() { return "boost"; } 68 | }; 69 | 70 | 71 | }}} 72 | 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /src/benchmarks/descriptors/signal/qt5.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SRC_BENCHMARKS_DESCRIPTORS_SIGNALS_QT5_HPP 2 | #define SRC_BENCHMARKS_DESCRIPTORS_SIGNALS_QT5_HPP 3 | 4 | #if WIGWAG_BENCHMARKS_QT5 5 | 6 | #define QT_NO_KEYWORDS 7 | #include 8 | 9 | 10 | namespace descriptors { 11 | namespace signal { 12 | namespace qt5 13 | { 14 | 15 | class SlotOwner : public QObject 16 | { 17 | Q_OBJECT 18 | 19 | public: 20 | SlotOwner() { } 21 | SlotOwner(const SlotOwner& other) { } 22 | 23 | public Q_SLOTS: 24 | void testSlot() { } 25 | }; 26 | 27 | 28 | class SlotWrapper 29 | { 30 | private: 31 | SlotOwner _slotOwner; 32 | const char* _slotName; 33 | 34 | public: 35 | SlotWrapper(const SlotOwner& slotOwner, const char* slotName) 36 | : _slotOwner(slotOwner), _slotName(slotName) 37 | { } 38 | 39 | const SlotOwner* getSlotOwner() const { return &_slotOwner; } 40 | const char* getSlotName() const { return _slotName; } 41 | }; 42 | 43 | 44 | class SignalConnectionWrapper 45 | { 46 | private: 47 | QMetaObject::Connection _c; 48 | 49 | public: 50 | SignalConnectionWrapper(const QMetaObject::Connection c) : _c(c) { } 51 | ~SignalConnectionWrapper() { QObject::disconnect(_c); } 52 | 53 | SignalConnectionWrapper(const SignalConnectionWrapper&) = delete; 54 | SignalConnectionWrapper& operator = (const SignalConnectionWrapper&) = delete; 55 | }; 56 | 57 | 58 | class SignalOwner : public QObject 59 | { 60 | Q_OBJECT 61 | 62 | public: 63 | SignalOwner() { } 64 | 65 | void invokeSignal() { Q_EMIT testSignal(); } 66 | 67 | QMetaObject::Connection connect(const SlotWrapper& slotWrapper) const 68 | { return QObject::connect(this, SIGNAL(testSignal()), slotWrapper.getSlotOwner(), slotWrapper.getSlotName()); } 69 | 70 | void operator () () 71 | { Q_EMIT testSignal(); } 72 | 73 | Q_SIGNALS: 74 | void testSignal(); 75 | }; 76 | 77 | 78 | struct Regular 79 | { 80 | using SignalType = SignalOwner; 81 | using HandlerType = SlotWrapper; 82 | using ConnectionType = SignalConnectionWrapper; 83 | 84 | static HandlerType MakeHandler() { return SlotWrapper(SlotOwner(), SLOT(testSlot())); } 85 | static std::string GetName() { return "qt5"; } 86 | }; 87 | 88 | }}} 89 | 90 | #endif 91 | 92 | #endif 93 | -------------------------------------------------------------------------------- /src/benchmarks/descriptors/signal/sigcpp.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SRC_BENCHMARKS_DESCRIPTORS_SIGNALS_SIGCPP_HPP 2 | #define SRC_BENCHMARKS_DESCRIPTORS_SIGNALS_SIGCPP_HPP 3 | 4 | #if WIGWAG_BENCHMARKS_SIGCPP2 5 | 6 | #include 7 | 8 | 9 | namespace descriptors { 10 | namespace signal { 11 | namespace sigcpp 12 | { 13 | 14 | class ScopedConnection 15 | { 16 | private: 17 | sigc::connection _connection; 18 | 19 | public: 20 | ScopedConnection(sigc::connection c) : _connection(std::move(c)) { } 21 | ~ScopedConnection() { _connection.disconnect(); } 22 | 23 | ScopedConnection(const ScopedConnection&) = delete; 24 | ScopedConnection& operator = (const ScopedConnection&) = delete; 25 | }; 26 | 27 | 28 | struct Regular 29 | { 30 | using SignalType = sigc::signal; 31 | using HandlerType = std::function; 32 | using ConnectionType = ScopedConnection; 33 | 34 | static HandlerType MakeHandler() { return []{}; } 35 | static std::string GetName() { return "sigcpp"; } 36 | }; 37 | 38 | }}} 39 | 40 | #endif 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/benchmarks/descriptors/signal/wigwag.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SRC_BENCHMARKS_DESCRIPTORS_SIGNALS_WIGWAG_HPP 2 | #define SRC_BENCHMARKS_DESCRIPTORS_SIGNALS_WIGWAG_HPP 3 | 4 | 5 | #include 6 | 7 | 8 | namespace descriptors { 9 | namespace signal { 10 | namespace wigwag 11 | { 12 | 13 | using namespace ::wigwag; 14 | 15 | template < typename Signature_ > 16 | using ui_signal = wigwag::signal; 17 | 18 | 19 | struct Regular 20 | { 21 | using SignalType = wigwag::signal; 22 | using HandlerType = std::function; 23 | using ConnectionType = token; 24 | 25 | static HandlerType MakeHandler() { return []{}; } 26 | static std::string GetName() { return "wigwag"; } 27 | }; 28 | 29 | 30 | struct Ui 31 | { 32 | using SignalType = ui_signal; 33 | using HandlerType = std::function; 34 | using ConnectionType = token; 35 | 36 | static HandlerType MakeHandler() { return []{}; } 37 | static std::string GetName() { return "wigwag_ui"; } 38 | }; 39 | 40 | }}} 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/benchmarks/main.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016, Dmitry Koplyarov 2 | // 3 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 4 | // provided that the above copyright notice and this permission notice appear in all copies. 5 | // 6 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 7 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 8 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 9 | 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #include 30 | 31 | 32 | int main(int argc, char* argv[]) 33 | { 34 | try 35 | { 36 | using namespace benchmarks; 37 | using namespace descriptors; 38 | 39 | BenchmarkSuite s; 40 | s.RegisterBenchmarks(); 52 | 53 | s.RegisterBenchmarks(); 56 | 57 | s.RegisterBenchmarks(); 62 | 63 | s.RegisterBenchmarks(); 67 | 68 | return BenchmarkApp(s).Run(argc, argv); 69 | } 70 | catch (const std::exception& ex) 71 | { 72 | std::cerr << "Uncaught exception: " << ex.what() << std::endl; 73 | return 1; 74 | } 75 | return 0; 76 | } 77 | -------------------------------------------------------------------------------- /src/test/compilation_test.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016, Dmitry Koplyarov 2 | // 3 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 4 | // provided that the above copyright notice and this permission notice appear in all copies. 5 | // 6 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 7 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 8 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 9 | 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | 18 | template < int > 19 | class constructor_tag 20 | { }; 21 | 22 | 23 | class observable_int 24 | { 25 | private: 26 | int _value; 27 | wigwag::signal _on_changed; 28 | 29 | public: 30 | observable_int(constructor_tag<1>) 31 | : _value(0), _on_changed(std::bind(&observable_int::on_changed_populator, this, std::placeholders::_1)) 32 | { } 33 | 34 | observable_int(constructor_tag<2>) 35 | : _value(0), _on_changed([&](const std::function& h){ h(this->_value); }) 36 | { } 37 | 38 | observable_int(constructor_tag<3>) 39 | : _value(0), _on_changed([&](const std::function& h){ h(_value); }) 40 | { } 41 | 42 | 43 | wigwag::signal_connector on_changed() const 44 | { return _on_changed.connector(); } 45 | 46 | const wigwag::signal& on_changed_ref() const 47 | { return _on_changed; } 48 | 49 | 50 | void set_value(int value) 51 | { 52 | std::lock_guard l(_on_changed.lock_primitive()); 53 | _value = value; 54 | _on_changed(_value); 55 | } 56 | 57 | private: 58 | void on_changed_populator(const std::function& handler) 59 | { handler(_value); } 60 | }; 61 | 62 | 63 | class int_observer 64 | { 65 | private: 66 | mutable std::mutex _mutex { }; 67 | int _value { }; 68 | wigwag::token_pool _tokens { }; 69 | std::shared_ptr _worker { std::make_shared() }; 70 | 71 | public: 72 | int_observer(const observable_int& i) 73 | { 74 | _tokens += i.on_changed().connect(_worker, std::bind(&int_observer::int_changed_async_handler, this, std::placeholders::_1)); 75 | _tokens += i.on_changed().connect(std::bind(&int_observer::int_changed_sync_handler, this, std::placeholders::_1)); 76 | } 77 | 78 | private: 79 | void int_changed_async_handler(int i) 80 | { 81 | std::lock_guard l(_mutex); 82 | _value = i; 83 | } 84 | 85 | void int_changed_sync_handler(int) 86 | { } 87 | }; 88 | 89 | 90 | class crazy_signals 91 | { 92 | public: 93 | wigwag::signal& f)> on_func; 94 | wigwag::signal on_string_ref; 95 | 96 | void test_connect() 97 | { 98 | std::shared_ptr worker = std::make_shared(); 99 | wigwag::token_pool tp; 100 | 101 | tp += on_func.connect(std::bind(&crazy_signals::func_handler, this, std::placeholders::_1)); 102 | tp += on_string_ref.connect(std::bind(&crazy_signals::string_ref_handler, this, std::placeholders::_1)); 103 | 104 | tp += on_func.connect(worker, std::bind(&crazy_signals::func_handler, this, std::placeholders::_1)); 105 | tp += on_string_ref.connect(worker, std::bind(&crazy_signals::string_ref_handler, this, std::placeholders::_1)); 106 | } 107 | 108 | void test_invoke() 109 | { 110 | std::string s; 111 | 112 | on_func([](int){ }); 113 | on_func(std::bind([](const std::string&, int){ }, "qwe", std::placeholders::_1)); 114 | on_string_ref(s); 115 | on_string_ref(std::ref(s)); 116 | } 117 | 118 | private: 119 | void func_handler(const std::function& f) { f(42); } 120 | void string_ref_handler(std::string& s) { s = "qwe"; } 121 | }; 122 | 123 | 124 | class instantiations_test 125 | { 126 | public: 127 | wigwag::signal s1; 128 | wigwag::signal s2; 129 | wigwag::signal s3; 130 | wigwag::signal s4; 131 | 132 | wigwag::listenable, wigwag::exception_handling::none> l1; 133 | wigwag::listenable, wigwag::threading::shared_recursive_mutex> l2; 134 | wigwag::listenable, wigwag::life_assurance::none, wigwag::state_populating::none> l3; 135 | 136 | instantiations_test() 137 | : s1(), 138 | s2(std::make_shared()), 139 | s3(), 140 | s4(std::make_shared()), 141 | l1(), 142 | l2(std::make_shared()), 143 | l3() 144 | { } 145 | 146 | void f() 147 | { 148 | s1.connect([]{}); 149 | s2.connect([]{}); 150 | s3.connect([]{}); 151 | s4.connect([]{}); 152 | l1.connect([]{}); 153 | l2.connect([]{}); 154 | l3.connect([]{}); 155 | } 156 | 157 | void f() const 158 | { 159 | s1(); 160 | s2(); 161 | s3(); 162 | s4(); 163 | l1.invoke([](const std::function& f){ f(); }); 164 | l2.invoke([](const std::function& f){ f(); }); 165 | l3.invoke([](const std::function& f){ f(); }); 166 | } 167 | }; 168 | -------------------------------------------------------------------------------- /src/test/no_exceptions_compilation_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016, Dmitry Koplyarov 2 | // 3 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 4 | // provided that the above copyright notice and this permission notice appear in all copies. 5 | // 6 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 7 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 8 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 9 | 10 | 11 | #include 12 | 13 | void no_exceptions_compilation_test_dummy_func() 14 | { } 15 | -------------------------------------------------------------------------------- /src/test/pedantic_compilation_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016, Dmitry Koplyarov 2 | // 3 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 4 | // provided that the above copyright notice and this permission notice appear in all copies. 5 | // 6 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 7 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 8 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 9 | 10 | 11 | #include 12 | 13 | void pedantic_compilation_test_dummy_func() 14 | { } 15 | -------------------------------------------------------------------------------- /src/test/utils/mutexed.hpp: -------------------------------------------------------------------------------- 1 | #ifndef UTILS_MUTEXED_HPP 2 | #define UTILS_MUTEXED_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | 16 | #include 17 | 18 | 19 | namespace wigwag 20 | { 21 | 22 | template < typename T_ > 23 | class mutexed 24 | { 25 | private: 26 | mutable std::mutex _m; 27 | T_ _val; 28 | 29 | public: 30 | mutexed(T_ val = T_()) 31 | : _val(val) 32 | { } 33 | 34 | T_ get() const 35 | { 36 | auto l = lock(_m); 37 | return _val; 38 | } 39 | 40 | void set(T_ val) 41 | { 42 | auto l = lock(_m); 43 | _val = val; 44 | } 45 | }; 46 | 47 | } 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /src/test/utils/profiler.hpp: -------------------------------------------------------------------------------- 1 | #ifndef UTILS_PROFILER_HPP 2 | #define UTILS_PROFILER_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | 16 | 17 | namespace wigwag 18 | { 19 | 20 | template < typename ClockT_ > 21 | class basic_profiler 22 | { 23 | typedef std::chrono::time_point TimePoint; 24 | 25 | private: 26 | TimePoint _start; 27 | 28 | public: 29 | basic_profiler() { _start = ClockT_::now(); } 30 | 31 | decltype(TimePoint() - TimePoint()) reset() 32 | { 33 | TimePoint end = ClockT_::now(); 34 | auto delta = end - _start; 35 | _start = end; 36 | return delta; 37 | } 38 | }; 39 | using profiler = basic_profiler; 40 | 41 | } 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /src/test/utils/thread.hpp: -------------------------------------------------------------------------------- 1 | #ifndef UTILS_UTILS_HPP 2 | #define UTILS_UTILS_HPP 3 | 4 | // Copyright (c) 2016, Dmitry Koplyarov 5 | // 6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 7 | // provided that the above copyright notice and this permission notice appear in all copies. 8 | // 9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 10 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 11 | // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | 13 | 14 | #include 15 | #include 16 | 17 | 18 | namespace wigwag 19 | { 20 | 21 | class thread 22 | { 23 | public: 24 | using thread_func = std::function&)>; 25 | 26 | private: 27 | std::atomic _alive; 28 | thread_func _thread_func; 29 | std::string _error_message; 30 | std::thread _impl; 31 | 32 | public: 33 | thread(const thread_func& f) 34 | : _alive(true), 35 | _thread_func(f) 36 | { _impl = std::thread(std::bind(&thread::func, this)); } 37 | 38 | ~thread() 39 | { 40 | _alive = false; 41 | 42 | if (_impl.joinable()) 43 | _impl.join(); 44 | else 45 | std::cerr << "WARNING: thread is not joinable!" << std::endl; 46 | 47 | if (!_error_message.empty()) 48 | TS_FAIL(("Uncaught exception in thread: " + _error_message).c_str()); 49 | } 50 | 51 | static void sleep(int64_t ms) 52 | { std::this_thread::sleep_for(std::chrono::milliseconds(ms)); } 53 | 54 | private: 55 | void func() 56 | { 57 | try 58 | { _thread_func(_alive); } 59 | catch (const std::exception& ex) 60 | { _error_message = ex.what(); } 61 | } 62 | }; 63 | 64 | 65 | template < typename Lockable_ > 66 | std::unique_lock lock(Lockable_& lockable) 67 | { return std::unique_lock(lockable); } 68 | 69 | } 70 | 71 | #endif 72 | --------------------------------------------------------------------------------