pax_global_header00006660000000000000000000000064125127567150014525gustar00rootroot0000000000000052 comment=d9e99842449752ec777beca1c21aff1c45a5008b actor-framework-0.13.2/000077500000000000000000000000001251275671500147135ustar00rootroot00000000000000actor-framework-0.13.2/.clang-format000066400000000000000000000020141251275671500172630ustar00rootroot00000000000000--- AccessModifierOffset: -1 AlignEscapedNewlinesLeft: false AlignTrailingComments: true AllowAllParametersOfDeclarationOnNextLine: false AllowShortIfStatementsOnASingleLine: false AllowShortLoopsOnASingleLine: false AlwaysBreakBeforeMultilineStrings: true AlwaysBreakTemplateDeclarations: true BinPackParameters: true BreakBeforeBinaryOperators: true BreakBeforeBraces: Attach BreakBeforeTernaryOperators: false ColumnLimit: 80 ConstructorInitializerAllOnOneLineOrOnePerLine: true ConstructorInitializerIndentWidth: 4 ContinuationIndentWidth: 2 Cpp11BracedListStyle: true IndentCaseLabels: true IndentFunctionDeclarationAfterType: false IndentWidth: 2 MaxEmptyLinesToKeep: 1 NamespaceIndentation: None PointerBindsToType: true SpaceBeforeAssignmentOperators: true SpaceAfterControlStatementKeyword: true SpaceInEmptyParentheses: false SpacesBeforeTrailingComments: 1 SpacesInAngles: false SpacesInCStyleCastParentheses: false SpacesInParentheses: false Standard: Cpp11 UseTab: Never BreakConstructorInitializersBeforeComma: false ... actor-framework-0.13.2/.gitignore000066400000000000000000000003221251275671500167000ustar00rootroot00000000000000*.DS_Store Doxyfile cppa.creator.user* html/ build/* cli_build/* build-clang/* build-gcc/* Makefile bin/* lib/* manual/build-pdf/* manual/build-html/* manual/*.toc manual/manual.html manual/variables.tex *.swp actor-framework-0.13.2/.gitmodules000066400000000000000000000007171251275671500170750ustar00rootroot00000000000000[submodule "benchmarks"] path = benchmarks url = https://github.com/actor-framework/benchmarks.git [submodule "nexus"] path = nexus url = https://github.com/actor-framework/nexus.git [submodule "opencl"] path = libcaf_opencl url = https://github.com/actor-framework/opencl.git [submodule "libcaf_riac"] path = libcaf_riac url = https://github.com/actor-framework/riac.git [submodule "cash"] path = cash url = https://github.com/actor-framework/cash.git actor-framework-0.13.2/CMakeLists.txt000066400000000000000000000501411251275671500174540ustar00rootroot00000000000000cmake_minimum_required(VERSION 2.8) project(caf C CXX) # silence policy CMP0042 warning by enabling RPATH explicitly if(APPLE AND NOT DEFINED CMAKE_MACOSX_RPATH) set(CMAKE_MACOSX_RPATH true) endif() ################################################################################ # make sure all variables are set to "no" if undefined for summary output # ################################################################################ if(NOT CAF_ENABLE_RUNTIME_CHECKS) set(CAF_ENABLE_RUNTIME_CHECKS no) endif() if(NOT CAF_NO_MEM_MANAGEMENT) set(CAF_NO_MEM_MANAGEMENT no) endif() if(NOT CAF_BUILD_STATIC_ONLY) set(CAF_BUILD_STATIC_ONLY no) endif() if(NOT CAF_BUILD_STATIC) set(CAF_BUILD_STATIC no) endif() if(NOT CAF_NO_OPENCL) set(CAF_NO_OPENCL no) endif() ################################################################################ # get version of CAF # ################################################################################ # read content of config.hpp file(READ "libcaf_core/caf/config.hpp" CONFIG_HPP) # get line containing the version string(REGEX MATCH "#define CAF_VERSION [0-9]+" VERSION_LINE "${CONFIG_HPP}") # extract version number from line string(REGEX MATCH "[0-9]+" VERSION_INT "${VERSION_LINE}") # calculate major, minor, and patch version math(EXPR CAF_VERSION_MAJOR "${VERSION_INT} / 10000") math(EXPR CAF_VERSION_MINOR "( ${VERSION_INT} / 100) % 100") math(EXPR CAF_VERSION_PATCH "${VERSION_INT} % 100") # create full version string set(CAF_VERSION "${CAF_VERSION_MAJOR}.${CAF_VERSION_MINOR}.${CAF_VERSION_PATCH}") ################################################################################ # set output paths for binaries and libraries if not provided by the user # ################################################################################ # prohibit in-source builds if("${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}") message(FATAL_ERROR "In-source builds are not allowed. Please use " "./configure to choose a build directory and " "initialize the build configuration.") endif() # set module path appropriately set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") # set binary output path if not defined by user if("${EXECUTABLE_OUTPUT_PATH}" STREQUAL "") set(EXECUTABLE_OUTPUT_PATH "${CMAKE_CURRENT_BINARY_DIR}/bin") endif() # set library output path if not defined by user, but always set # library output path to binary output path for Xcode projects if("${CMAKE_GENERATOR}" STREQUAL "Xcode") set(LIBRARY_OUTPUT_PATH "${EXECUTABLE_OUTPUT_PATH}") elseif("${LIBRARY_OUTPUT_PATH}" STREQUAL "") set(LIBRARY_OUTPUT_PATH "${CMAKE_CURRENT_BINARY_DIR}/lib") endif() ################################################################################ # compiler setup # ################################################################################ # check for g++ >= 4.7 or clang++ > = 3.2 if(NOT WIN32 AND NOT NO_COMPILER_CHECK) try_run(ProgramResult CompilationSucceeded "${CMAKE_CURRENT_BINARY_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/get_compiler_version.cpp" RUN_OUTPUT_VARIABLE CompilerVersion) if(NOT CompilationSucceeded OR NOT ProgramResult EQUAL 0) message(FATAL_ERROR "Cannot determine compiler version") elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") if(CompilerVersion VERSION_GREATER 4.6) message(STATUS "Found g++ version ${CompilerVersion}") else() message(FATAL_ERROR "g++ >= 4.7 required (found: ${CompilerVersion})") endif() elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") if(CompilerVersion VERSION_GREATER 3.1) message(STATUS "Found clang++ version ${CompilerVersion}") else() message(FATAL_ERROR "clang++ >= 3.2 required (found: ${CompilerVersion})") endif() else() message(FATAL_ERROR "Your C++ compiler does not support C++11 " "or is not supported") endif() endif() # set optional build flags set(EXTRA_FLAGS "") # add "-Werror" flag if --pedantic-build is used if(CXX_WARNINGS_AS_ERROS) set(EXTRA_FLAGS "-Werror") endif() # enable a ton of warnings if --more-clang-warnings is used if(MORE_WARNINGS) if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") set(WFLAGS "-Weverything -Wno-c++98-compat -Wno-padded " "-Wno-documentation-unknown-command -Wno-exit-time-destructors " "-Wno-global-constructors -Wno-missing-prototypes " "-Wno-c++98-compat-pedantic -Wno-unused-member-function " "-Wno-unused-const-variable -Wno-switch-enum " "-Wno-missing-noreturn -Wno-covered-switch-default") elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") set(WFLAGS "-Waddress -Wall -Warray-bounds " "-Wattributes -Wbuiltin-macro-redefined -Wcast-align " "-Wcast-qual -Wchar-subscripts -Wclobbered -Wcomment " "-Wconversion -Wconversion-null -Wcoverage-mismatch " "-Wcpp -Wdelete-non-virtual-dtor -Wdeprecated " "-Wdeprecated-declarations -Wdiv-by-zero -Wdouble-promotion " "-Wempty-body -Wendif-labels -Wenum-compare -Wextra " "-Wfloat-equal -Wformat -Wfree-nonheap-object " "-Wignored-qualifiers -Winit-self " "-Winline -Wint-to-pointer-cast -Winvalid-memory-model " "-Winvalid-offsetof -Wlogical-op -Wmain -Wmaybe-uninitialized " "-Wmissing-braces -Wmissing-field-initializers -Wmultichar " "-Wnarrowing -Wnoexcept -Wnon-template-friend " "-Wnon-virtual-dtor -Wnonnull -Woverflow " "-Woverlength-strings -Wparentheses " "-Wpmf-conversions -Wpointer-arith -Wreorder " "-Wreturn-type -Wsequence-point -Wshadow " "-Wsign-compare -Wswitch -Wtype-limits -Wundef " "-Wuninitialized -Wunused -Wvla -Wwrite-strings") endif() # convert CMake list to a single string, erasing the ";" separators string(REPLACE ";" "" WFLAGS_STR ${WFLAGS}) set(EXTRA_FLAGS "${EXTRA_FLAGS} ${WFLAGS_STR}") endif() # add -stdlib=libc++ when using Clang if possible if(NOT NO_AUTO_LIBCPP AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") set(CXXFLAGS_BACKUP "${CMAKE_CXX_FLAGS}") set(CMAKE_CXX_FLAGS "-std=c++11 -stdlib=libc++") try_run(ProgramResult CompilationSucceeded "${CMAKE_CURRENT_BINARY_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/get_compiler_version.cpp" RUN_OUTPUT_VARIABLE CompilerVersion) if(NOT CompilationSucceeded OR NOT ProgramResult EQUAL 0) message(STATUS "Use clang with GCC' libstdc++") else() message(STATUS "Automatically added '-stdlib=libc++' flag " "(NO_AUTO_LIBCPP not defined)") set(EXTRA_FLAGS "${EXTRA_FLAGS} -stdlib=libc++") endif() # restore CXX flags set(CMAKE_CXX_FLAGS "${CXXFLAGS_BACKUP}") endif() # enable address sanitizer if requested by the user if(ENABLE_ADDRESS_SANITIZER) # check whether address sanitizer is available set(CXXFLAGS_BACKUP "${CMAKE_CXX_FLAGS}") set(CMAKE_CXX_FLAGS "-fsanitize=address -fno-omit-frame-pointer") try_run(ProgramResult CompilationSucceeded "${CMAKE_CURRENT_BINARY_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/get_compiler_version.cpp") if(NOT CompilationSucceeded) message(WARNING "Address Sanitizer is not available on selected compiler") else() message(STATUS "Enable Address Sanitizer") set(EXTRA_FLAGS "${EXTRA_FLAGS} -fsanitize=address -fno-omit-frame-pointer") endif() # restore CXX flags set(CMAKE_CXX_FLAGS "${CXXFLAGS_BACKUP}") endif(ENABLE_ADDRESS_SANITIZER) # -pthread is ignored on MacOSX but required on other platforms if(NOT APPLE AND NOT WIN32) set(EXTRA_FLAGS "${EXTRA_FLAGS} -pthread") endif() # -fPIC generates warnings on MinGW plus extra setup steps needed on MinGW if(MINGW) add_definitions(-D_WIN32_WINNT=0x0600) add_definitions(-DWIN32) include(GenerateExportHeader) set(LD_FLAGS "ws2_32 -liphlpapi") # build static to avoid runtime dependencies to GCC libraries set(EXTRA_FLAGS "${EXTRA_FLAGS} -static") else() set(EXTRA_FLAGS "${EXTRA_FLAGS} -fPIC") endif() # iOS support if(CAF_OSX_SYSROOT) set(CMAKE_OSX_SYSROOT "${CAF_OSX_SYSROOT}") endif() if(CAF_IOS_DEPLOYMENT_TARGET) if("${CAF_OSX_SYSROOT}" STREQUAL "iphonesimulator") set(EXTRA_FLAGS "${EXTRA_FLAGS} -mios-simulator-version-min=${CAF_IOS_DEPLOYMENT_TARGET}") else() set(EXTRA_FLAGS "${EXTRA_FLAGS} -miphoneos-version-min=${CAF_IOS_DEPLOYMENT_TARGET}") endif() endif() # check if the user provided CXXFLAGS, set defaults otherwise if(CMAKE_CXX_FLAGS) set(CMAKE_CXX_FLAGS_DEBUG "") set(CMAKE_CXX_FLAGS_MINSIZEREL "") set(CMAKE_CXX_FLAGS_RELEASE "") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "") else() set(CMAKE_CXX_FLAGS "-std=c++11 -Wextra -Wall -pedantic ${EXTRA_FLAGS}") set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g") set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os") set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g") endif() # set build default build type to RelWithDebInfo if not set if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE RelWithDebInfo) endif() # needed by subprojects set(LD_FLAGS ${LD_FLAGS} ${CMAKE_LD_LIBS}) ################################################################################ # add custom definitions requested via configure script # ################################################################################ if(CAF_LOG_LEVEL) add_definitions(-DCAF_LOG_LEVEL=${CAF_LOG_LEVEL}) endif() if(CAF_ENABLE_RUNTIME_CHECKS) add_definitions(-DCAF_ENABLE_RUNTIME_CHECKS) endif() if(CAF_NO_MEM_MANAGEMENT) add_definitions(-DCAF_NO_MEM_MANAGEMENT) endif() ################################################################################ # setup for install target # ################################################################################ # install includes from core install(DIRECTORY libcaf_core/caf/ DESTINATION include/caf FILES_MATCHING PATTERN "*.hpp") # install CPPA compatibility headers install(DIRECTORY libcaf_core/cppa/ DESTINATION include/cppa FILES_MATCHING PATTERN "*.hpp") # install includes from io install(DIRECTORY libcaf_io/caf/ DESTINATION include/caf FILES_MATCHING PATTERN "*.hpp") # install includes from opencl if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/libcaf_opencl/CMakeLists.txt") install(DIRECTORY libcaf_opencl/caf/ DESTINATION include/caf FILES_MATCHING PATTERN "*.hpp") endif() # process cmake_uninstall.cmake.in configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY) # add uninstall target add_custom_target(uninstall COMMAND "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake") ################################################################################ # set inclue paths for subprojects # ################################################################################ # path to caf core & io headers set(LIBCAF_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/libcaf_core" "${CMAKE_CURRENT_SOURCE_DIR}/libcaf_io") # path to caf opencl headers if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/libcaf_opencl/CMakeLists.txt") set(LIBCAF_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/libcaf_opencl/" "${LIBCAF_INCLUDE_DIRS}") endif() # all projects need the headers of the core components include_directories("${LIBCAF_INCLUDE_DIRS}") ################################################################################ # add subprojects # ################################################################################ # core library message(STATUS "Enter subdirectory libcaf_core") add_subdirectory(libcaf_core) # set core lib for sub directories if(NOT CAF_BUILD_STATIC_ONLY) set(LIBCAF_CORE_LIBRARY libcaf_core_shared) else() set(LIBCAF_CORE_LIBRARY libcaf_core_static) endif() message(STATUS "Enter subdirectory libcaf_io") add_subdirectory(libcaf_io) # set io lib for sub directories if(NOT CAF_BUILD_STATIC_ONLY) set(LIBCAF_IO_LIBRARY libcaf_io_shared) else() set(LIBCAF_IO_LIBRARY libcaf_io_static) endif() # set opencl lib for sub directories if not told otherwise if(NOT CAF_NO_OPENCL AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/libcaf_opencl/CMakeLists.txt") message(STATUS "Enter subdirectory libcaf_opencl") find_package(OPENCL REQUIRED) add_subdirectory(libcaf_opencl) if(NOT CAF_BUILD_STATIC_ONLY) set(LIBCAF_OPENCL_LIBRARY libcaf_opencl_shared) else() set(LIBCAF_OPENCL_LIBRARY libcaf_opencl_static) endif() endif() # tell CMake caf_io depends on caf_core add_dependencies(libcaf_io libcaf_core) # set LIBCAF_LIBRARIES for other subprojects set(LIBCAF_LIBRARIES "${LIBCAF_CORE_LIBRARY}" "${LIBCAF_IO_LIBRARY}" "${LIBCAF_OPENCL_LIBRARY}") # add unit tests if not being told otherwise if(NOT CAF_NO_UNIT_TESTS) enable_testing() message(STATUS "Enter subdirectory unit_testing") add_subdirectory(unit_testing) add_dependencies(all_unit_tests libcaf_core libcaf_io) if(NOT CAF_NO_OPENCL AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/libcaf_opencl/CMakeLists.txt") add_subdirectory(libcaf_opencl/unit_testing) endif() endif() # build examples if not being told otherwise if(NOT CAF_NO_EXAMPLES) message(STATUS "Enter subdirectory examples") add_subdirectory(examples) add_dependencies(all_examples libcaf_core libcaf_io) if(NOT CAF_NO_OPENCL AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/libcaf_opencl/CMakeLists.txt") add_subdirectory(libcaf_opencl/examples) add_dependencies(opencl_examples libcaf_opencl) endif() endif() # build RIAC if not being told otherwise if(NOT CAF_NO_RIAC AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/libcaf_riac/CMakeLists.txt") message(STATUS "Enter subdirectory probe") add_subdirectory(libcaf_riac) add_dependencies(libcaf_riac libcaf_core libcaf_io) if(NOT CAF_BUILD_STATIC_ONLY) set(LIBCAF_LIBRARIES "${LIBCAF_LIBRARIES}" libcaf_riac_shared) else() set(LIBCAF_LIBRARIES "${LIBCAF_LIBRARIES}" libcaf_riac_static) endif() # add headers to include directories so other subprojects can use RIAC include_directories("${LIBCAF_INCLUDE_DIRS}" "${CMAKE_CURRENT_SOURCE_DIR}/libcaf_riac") # add libcaf_riac to the list of caf libraries set(CAF_HAS_RIAC yes) else() set(CAF_HAS_RIAC no) endif() # build nexus if not being told otherwise if(NOT CAF_NO_NEXUS AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/nexus/CMakeLists.txt") if(NOT CAF_HAS_RIAC) message(WARNING "cannot build nexus without RIAC submodule") set(CAF_NO_NEXUS yes) else() message(STATUS "Enter subdirectory nexus") add_subdirectory(nexus) add_dependencies(nexus libcaf_riac) set(CAF_NO_NEXUS no) endif() else() # make sure variable is set for build log set(CAF_NO_NEXUS yes) endif() # build cash if not being told otherwise if(NOT CAF_NO_CASH AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cash/CMakeLists.txt") if(NOT CAF_HAS_RIAC) message(WARNING "cannot build cash without RIAC submodule") set(CAF_NO_CASH yes) else() message(STATUS "Enter subdirectory cash") add_subdirectory(cash) add_dependencies(cash libcaf_riac) set(CAF_NO_CASH no) endif() else() # make sure variable is set for build log set(CAF_NO_CASH yes) endif() # build benchmarks if not being told otherwise if(NOT CAF_NO_BENCHMARKS AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/benchmarks/CMakeLists.txt") message(STATUS "Enter subdirectory benchmarks") add_subdirectory(benchmarks) add_dependencies(all_benchmarks libcaf_io) else() # make sure variable is set for build log set(CAF_NO_BENCHMARKS yes) endif() ################################################################################ # LateX setup # ################################################################################ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/manual/variables.tex.in" "${CMAKE_CURRENT_SOURCE_DIR}/manual/variables.tex" @ONLY) ################################################################################ # Doxygen setup # ################################################################################ # check for doxygen and add custom "doc" target to Makefile find_package(Doxygen) if(DOXYGEN_FOUND) configure_file("${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in" "${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile" @ONLY) add_custom_target(doc "${DOXYGEN_EXECUTABLE}" "${CMAKE_HOME_DIRECTORY}/Doxyfile" WORKING_DIRECTORY "${CMAKE_HOME_DIRECTORY}" COMMENT "Generating API documentation with Doxygen" VERBATIM) endif(DOXYGEN_FOUND) ################################################################################ # Add additional project files to GUI # ################################################################################ add_custom_target(gui_dummy SOURCES configure) ################################################################################ # print summary # ################################################################################ # set human-readable representation for log level set(LOG_LEVEL_STR "none") if(CAF_LOG_LEVEL) if(${CAF_LOG_LEVEL} EQUAL 0) set(LOG_LEVEL_STR "ERROR") elseif(${CAF_LOG_LEVEL} EQUAL 1) set(LOG_LEVEL_STR "WARNING") elseif(${CAF_LOG_LEVEL} EQUAL 2) set(LOG_LEVEL_STR "INFO") elseif(${CAF_LOG_LEVEL} EQUAL 3) set(LOG_LEVEL_STR "DEBUG") elseif(${CAF_LOG_LEVEL} EQUAL 4) set(LOG_LEVEL_STR "TRACE") else() set(LOG_LEVEL_STR "invalid") endif() endif() # little helper macro to invert a boolean macro(invertYesNo in out) if(${in}) set(${out} no) else() set(${out} yes) endif() endmacro() # invert CAF_NO_* variables for nicer output invertYesNo(CAF_NO_EXAMPLES CAF_BUILD_EXAMPLES) invertYesNo(CAF_NO_UNIT_TESTS CAF_BUILD_UNIT_TESTS) invertYesNo(CAF_NO_NEXUS CAF_BUILD_NEXUS) invertYesNo(CAF_NO_CASH CAF_BUILD_CASH) invertYesNo(CAF_NO_MEM_MANAGEMENT CAF_BUILD_MEM_MANAGEMENT) invertYesNo(CAF_NO_BENCHMARKS CAF_BUILD_BENCHMARKS) invertYesNo(CAF_NO_OPENCL CAF_BUILD_OPENCL) # collect all compiler flags string(TOUPPER "${CMAKE_BUILD_TYPE}" UPPER_BUILD_TYPE) set(ALL_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${UPPER_BUILD_TYPE}}") # done message(STATUS "\n====================| Build Summary |====================" "\n" "\nLibcaf version: ${CAF_VERSION}" "\n" "\nBuild type: ${CMAKE_BUILD_TYPE}" "\nBuild static: ${CAF_BUILD_STATIC}" "\nBulid static only: ${CAF_BUILD_STATIC_ONLY}" "\nRuntime checks: ${CAF_ENABLE_RUNTIME_CHECKS}" "\nLog level: ${LOG_LEVEL_STR}" "\nWith mem. mgmt.: ${CAF_BUILD_MEM_MANAGEMENT}" "\n" "\nBuild examples: ${CAF_BUILD_EXAMPLES}" "\nBuild unit tests: ${CAF_BUILD_UNIT_TESTS}" "\nBuild riac: ${CAF_HAS_RIAC}" "\nBuild nexus: ${CAF_BUILD_NEXUS}" "\nBuild cash: ${CAF_BUILD_CASH}" "\nBuild benchmarks: ${CAF_BUILD_BENCHMARKS}" "\nBuild opencl: ${CAF_BUILD_OPENCL}" "\n" "\nCXX: ${CMAKE_CXX_COMPILER}" "\nCXXFLAGS: ${ALL_CXX_FLAGS}" "\nLIBRARIES: ${LD_FLAGS}" "\n" "\nSource directory: ${CMAKE_CURRENT_SOURCE_DIR}" "\nBuild directory: ${CMAKE_CURRENT_BINARY_DIR}" "\nExecutable path: ${EXECUTABLE_OUTPUT_PATH}" "\nLibrary path: ${LIBRARY_OUTPUT_PATH}" "\nInstall prefix: ${CMAKE_INSTALL_PREFIX}" "\nGenerator: ${CMAKE_GENERATOR}" "\n" "\n===========================================================\n") actor-framework-0.13.2/Doxyfile.in000066400000000000000000001700661251275671500170400ustar00rootroot00000000000000# Doxyfile 1.8.0 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Enable markdown support #--------------------------------------------------------------------------- MARKDOWN_SUPPORT = YES #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = libcaf # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = @CAF_VERSION@ # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, # Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), # Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, # Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, Slovene, # Spanish, Swedish, and Ukrainian. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = YES # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 2 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it parses. # With this tag you can assign which parser to use for a given extension. # Doxygen has a built-in mapping, but you can override or extend it using this tag. # The format is ext=language, where ext is a file extension, and language is one of # the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, # Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat # .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), # use: inc=Fortran f=C EXTENSION_MAPPING = C++ # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = YES # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate getter # and setter methods for a property. Setting this option to YES (the default) # will make doxygen to replace the get and set methods by a property in the # documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = NO # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = YES # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespace are hidden. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = YES # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = NO # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = NO # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = YES # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = YES # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = NO # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. # This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by # doxygen. The layout file controls the global structure of the generated output files # in an output format independent way. The create the layout file that represents # doxygen's defaults, run doxygen with the -l option. You can optionally specify a # file name after the option, if omitted DoxygenLayout.xml will be used as the name # of the layout file. LAYOUT_FILE = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be abled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = YES # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = @CMAKE_HOME_DIRECTORY@/libcaf_core/caf @CMAKE_HOME_DIRECTORY@/libcaf_core/caf/mixin @CMAKE_HOME_DIRECTORY@/libcaf_core/caf/policy @CMAKE_HOME_DIRECTORY@/libcaf_io/caf/io # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 FILE_PATTERNS = # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = examples # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = YES # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. # If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. # Doxygen will compare the file name with each pattern and apply the # filter if there is a match. # The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = NO # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. # Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = NO #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = YES # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. For this to work a browser that supports # JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox # Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). HTML_DYNAMIC_SECTIONS = NO # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER # are set, an additional index file will be generated that can be used as input for # Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated # HTML documentation. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can # be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. # For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters QHP_CUST_FILTER_NAME = # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see # Qt Help Project / Custom Filters. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's # filter section matches. # Qt Help Project / Filter Attributes. QHP_SECT_FILTER_ATTRS = # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. QHG_LOCATION = # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 1 # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to FRAME, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, # Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are # probably better off using the HTML help feature. Other possible values # for this tag are: HIERARCHIES, which will generate the Groups, Directories, # and Class Hierarchy pages using a tree view instead of an ordered list; # ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which # disables this behavior completely. For backwards compatibility with previous # releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE # respectively. GENERATE_TREEVIEW = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. # This is useful # if you want to understand what is going on. # On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = CAF_DOCUMENTATION # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone # on a line, have an all uppercase name, and do not end with a semicolon. Such # function macros are typically used for boiler-plate code, and will confuse # the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option is superseded by the HAVE_DOT option below. This is only a # fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the output directory to look for the # FreeSans.ttf font (which doxygen will put there itself). If you specify a # different font using DOT_FONTNAME you can set the path where dot # can find it using this tag. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = YES # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not # seem to support this out of the box. Warning: Depending on the platform used, # enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Options related to the search engine #--------------------------------------------------------------------------- # The SEARCHENGINE tag specifies whether or not a search engine should be # used. If set to NO the values of all tags below this one will be ignored. SEARCHENGINE = YES actor-framework-0.13.2/HACKING.md000066400000000000000000000253151251275671500163070ustar00rootroot00000000000000This document specifies the coding style for the C++ Actor Framework. The style is loosely based on the [Google C++ Style Guide](http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml) and the coding conventions used by the STL. Example for the Impatient ========================= ```cpp // libcaf_example/caf/example/my_class.hpp #ifndef CAF_EXAMPLE_MY_CLASS_HPP #define CAF_EXAMPLE_MY_CLASS_HPP #include namespace caf { namespace example { /** * This class is only being used as style guide example. */ class my_class { public: /** * Brief description. More description. Note that CAF uses the * "JavaDoc-style" autobrief option, i.e., everything up until the * first dot is the brief description. */ my_class(); /** * Destructs `my_class`. Please use Markdown in comments. */ ~my_class(); // do not use the @return if you start the brief description with "Returns" /** * Returns the name of this instance. */ inline const std::string& name() const { return m_name; } /** * Sets the name of this instance. */ inline void name(std::string new_name) { m_name = std::move(new_name); } /** * Prints the name to `STDIN`. */ void print_name() const; /** * Does something (maybe). */ void do_something(); /** * Does something else. */ void do_something_else(); private: std::string m_name; }; } // namespace example } // namespace caf #endif // CAF_EXAMPLE_MY_CLASS_HPP ``` ```cpp // libcaf_example/src/my_class.cpp #include "caf/example/my_class.hpp" #include namespace caf { namespace example { namespace { constexpr const char default_name[] = "my object"; } // namespace my_class::my_class() : m_name(default_name) { // nop } my_class::~my_class() { // nop } void my_class::print_name() const { std::cout << name() << std::endl; } void my_class::do_something() { if (name() == default_name) { std::cout << "You didn't gave me a proper name, so I " << "refuse to do something." << std::endl; } else { std::cout << "You gave me the name " << name() << "... Do you really think I'm willing to do something " "for you after insulting me like that?" << std::endl; } } void::my_class::do_something_else() { switch (default_name[0]) { case 'a': // handle a break; case 'b': // handle b break; default: handle_default(); } } } // namespace example } // namespace caf ``` General rules ============= - Use 2 spaces per indentation level. - The maximum number of characters per line is 80. - Never use tabs. - Vertical whitespaces separate functions and are not used inside functions: use comments to document logical blocks. - Header filenames end in `.hpp`, implementation files end in `.cpp`. - Never declare more than one variable per line. - `*` and `&` bind to the *type*, e.g., `const std::string& arg`. - Namespaces do not increase the indentation level. - Access modifiers, e.g. `public`, are indented one space. - Use the order `public`, `protected`, and then `private`. - Always use `auto` to declare a variable unless you cannot initialize it immediately or if you actually want a type conversion. In the latter case, provide a comment why this conversion is necessary. - Never use unwrapped, manual resource management such as `new` and `delete`. - Do not use `typedef`. The syntax provided by `using` is much cleaner. - Use `typename` only when referring to dependent names. - Keywords are always followed by a whitespace: `if (...)`, `template <...>`, `while (...)`, etc. - Always use `{}` for bodies of control structures such as `if` or `while`, even for bodies consiting only of a single statement. - Opening braces belong to the same line: ```cpp if (my_condition) { my_fun(); } else { my_other_fun(); } ``` - Use standard order for readability: C standard libraries, C++ standard libraries, other libraries, (your) CAF headers: ```cpp #include #include #include "some/other/library.hpp" #include "caf/example/myclass.hpp" ``` - When declaring a function, the order of parameters is: outputs, then inputs. This follows the parameter order from the STL. - Never use C-style casts. Naming ====== - Class names, constants, and function names are all-lowercase with underscores. - Types and variables should be nouns, while functions performing an action should be "command" verbs. Classes used to implement metaprogramming functions also should use verbs, e.g., `remove_const`. - Member variables use the prefix `m_`. - Thread-local variables use the prefix `t_`. - Static, non-const variables are declared in the anonymous namespace and use the prefix `s_`. - Template parameter names use CamelCase. - Getter and setter use the name of the member without the `m_` prefix: ```cpp class some_fun { public: // ... int value() const { return m_value; } void value(int new_value) { m_value = new_value; } private: int m_value; }; ``` - Use `T` for generic, unconstrained template parameters and `x` for generic function arguments. Suffix both with `s` for template parameter packs: ```cpp template void print(const Ts&... xs) { // ... } ``` Headers ======= - Each `.cpp` file has an associated `.hpp` file. Exceptions to this rule are unit tests and `main.cpp` files. - Each class has its own pair of header and implementation files and the relative path for the header file is derived from its full name. For example, the header file for `caf::example::my_class` of `libcaf_example` is located at `libcaf_example/caf/example/my_class.hpp` and the source file at `libcaf_example/src/my_class.cpp`. - All header files should use `#define` guards to prevent multiple inclusion. The symbol name is `____HPP`. - Do not `#include` when a forward declaration suffices. - Each library component must provide a `fwd.hpp` header providing forward declartations for all types used in the user API. - Each library component must provide an `all.hpp` header that contains the main page for the documentation and includes all headers for the user API. - Use `inline` for small functions (rule of thumb: 10 lines or less). Breaking Statements =================== - Break constructor initializers after the comma, use four spaces for indentation, and place each initializer on its own line (unless you don't need to break at all): ```cpp my_class::my_class() : my_base_class(some_function()), m_greeting("Hello there! This is my_class!"), m_some_bool_flag(false) { // ok } other_class::other_class() : m_name("tommy"), m_buddy("michael") { // ok } ``` - Break function arguments after the comma for both declaration and invocation: ```cpp intptr_t channel::compare(const abstract_channel* lhs, const abstract_channel* rhs) { // ... } ``` - Break before tenary operators and before binary operators: ```cpp if (today_is_a_sunny_day() && it_is_not_too_hot_to_go_swimming()) { // ... } ``` Template Metaprogramming ======================== Despite its power, template metaprogramming came to the language pretty much by accident. Templates were never meant to be used for compile-time algorithms and type transformations. This is why C++ punishes metaprogramming with an insane amount of syntax noise. In CAF, we make excessive use of templates. To keep the code readable despite all the syntax noise, we have some extra rules for formatting metaprogramming code. - Brake `using name = ...` statements always directly after `=` if it does not fit in one line. - Consider the *semantics* of a metaprogramming function. For example, `std::conditional` is an if-then-else construct. Hence, place the if-clause on its own line and do the same for the two cases. - Use one level of indentation per "open" template and place the closing `>`, `>::type` or `>::value` on its own line. For example: ```cpp using optional_result_type = typename std::conditional< std::is_same::value, bool, optional >::type; // think of it as the following (not valid C++): auto optional_result_type = conditional { if result_type == void then bool else optional }; ``` - Note that this is not necessary when simply defining a type alias. When dealing with "ordinary" templates, indenting based on the position of the opening `<` is ok, e.g.: ```cpp using response_handle_type = response_handle; ``` Rvalue References ================= - Use rvalue references whenever it makes sense. - Write move constructors and assignment operators if possible. Preprocessor Macros =================== - Use macros if and only if you can't get the same result by using inline functions or proper constants. - Macro names use the form `CAF__`. General Git Rules ================= - The first line is a capitalized summary and has at most 50 characters. - The second line is left empty. - Optional long descriptions begin on the third line with a at most 72 characters per line. - Write commit messages in the imperative: "Fix bug" and not "Fixes bug" or "Fixed bug". Git Branches and Work Flow ========================== - The `master` branch always reflects a *production-ready* state, i.e., the latest release version. - The `develop` branch is the main branch. Every time it reaches a stable point it is merged back to `master` for a new release. The `develop` branch reflects the latest state of development and should always compile. - Simple bugfixes consisting of a single commit can be pushed to `develop`. - Fixes for critical issues can be pushed to the `master` (and `develop`) branch after talking to the maintainer (and then cause a new release immediately). - New features or non-trivial fixes are developed in a *topic branch* using the naming convention `topic/short-description`. Topic branches are merged off from `develop`. Finishing topic branches includes these steps: + Create a *pull request* to `develop` on GitHub + Wait for the results of Jenkins and fix any issues that might come up + Squash your commits if necessary once Jenkins succeeds + Ask the maintainer to review your changes if you have green light from Jenkins and a clean Git history for your work + The maintainer will merge the topic branch back into `develop` after the review phase is done (and you once again have a clean Git history) actor-framework-0.13.2/LICENSE000066400000000000000000000027561251275671500157320ustar00rootroot00000000000000Copyright (c) 2011-2014, Dominik Charousset All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. actor-framework-0.13.2/LICENSE_ALTERNATIVE000066400000000000000000000024721251275671500175630ustar00rootroot00000000000000Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. actor-framework-0.13.2/README.md000066400000000000000000000050061251275671500161730ustar00rootroot00000000000000CAF: C++ Actor Framework ======================== [![Jenkins][jenkins-badge]](http://mobi39.cpt.haw-hamburg.de/view/CAF%20Dashboard) [![Gitter][gitter-badge]](https://gitter.im/actor-framework/chat) [jenkins-badge]: http://mobi39.cpt.haw-hamburg.de/buildStatus/icon?job=CAF/master%20branch [gitter-badge]: https://badges.gitter.im/Join%20Chat.svg CAF is an open source C++11 actor model implementation featuring lightweight & fast actor implementations, pattern matching for messages, network transparent messaging, and more. On the Web ---------- * __Homepage__: http://www.actor-framework.org * __Developer Blog__: http://blog.actor-framework.org * __Doxygen (HTML)__: http://www.actor-framework.org/doc * __Manual (HTML)__: http://www.actor-framework.org/manual * __Manual (PDF)__: http://www.actor-framework.org/pdf/manual.pdf * __Mailing List__: https://groups.google.com/d/forum/actor-framework * __Chat__: https://gitter.im/actor-framework/chat Get the Sources --------------- * git clone https://github.com/actor-framework/actor-framework.git * cd actor-framework First Steps ----------- * ./configure * make * make install [as root, optional] It is recommended to run the unit tests as well. * make test Please submit a bug report that includes (a) your compiler version, (b) your OS, and (c) the content of the file build/Testing/Temporary/LastTest.log if an error occurs. Dependencies ------------ * CMake * Pthread (until C++11 compilers support the new `thread_local` keyword) Supported Compilers ------------------- * GCC >= 4.7.2 * Clang >= 3.2 Supported Operating Systems --------------------------- * Linux * Mac OS X * FreeBSD 10 * *Note for MS Windows*: CAF relies on C++11 features such as variadic templates and unrestricted unions. We will support Visual Studio as soon as Microsoft's compiler implements all required C++11 features. In the meantime, you can use CAF via MinGW. Scientific Use -------------- If you use CAF in a scientific context, please use the following citation: ``` @inproceedings{cshw-nassp-13, author = {Dominik Charousset and Thomas C. Schmidt and Raphael Hiesgen and Matthias W{\"a}hlisch}, title = {{Native Actors -- A Scalable Software Platform for Distributed, Heterogeneous Environments}}, booktitle = {Proc. of the 4rd ACM SIGPLAN Conference on Systems, Programming, and Applications (SPLASH '13), Workshop AGERE!}, month = {Oct.}, year = {2013}, publisher = {ACM}, address = {New York, NY, USA}, } ``` You will find the paper on http://dx.doi.org/10.1145/2541329.2541336 actor-framework-0.13.2/benchmarks/000077500000000000000000000000001251275671500170305ustar00rootroot00000000000000actor-framework-0.13.2/cash/000077500000000000000000000000001251275671500156315ustar00rootroot00000000000000actor-framework-0.13.2/cmake/000077500000000000000000000000001251275671500157735ustar00rootroot00000000000000actor-framework-0.13.2/cmake/FindLibcaf.cmake000066400000000000000000000103261251275671500207600ustar00rootroot00000000000000# Try to find libcaf headers and library. # # Use this module as follows: # # find_package(Libcaf) # # Variables used by this module (they can change the default behaviour and need # to be set before calling find_package): # # LIBCAF_ROOT_DIR Set this variable to the root installation of # libcaf if the module has problems finding # the proper installation path. # # Variables defined by this module: # # LIBCAF_FOUND System has libcaf headers and library # LIBCAF_LIBRARIES List of library files for all components # LIBCAF_INCLUDE_DIRS List of include paths for all components # LIBCAF_LIBRARY_$C Library file for component $C # LIBCAF_INCLUDE_DIR_$C Include path for component $C # iterate over user-defined components foreach (comp ${Libcaf_FIND_COMPONENTS}) # we use uppercase letters only for variable names string(TOUPPER "${comp}" UPPERCOMP) if ("${comp}" STREQUAL "core") set(HDRNAME "caf/all.hpp") else () set(HDRNAME "caf/${comp}/all.hpp") endif () # look for headers: give CMake hints where to find non-installed CAF versions # note that we look for the headers of each component individually: this is # necessary to support non-installed versions of CAF, i.e., accessing the # checked out "actor-framework" or "caf" directory structure directly; # also check whether LIBCAF_ROOT_DIR is a source directory set(HDRHINT "${LIBCAF_ROOT_DIR}/libcaf_${comp}") foreach(dir ".." "../.." "../../..") foreach(subdir "actor-framework" "caf") set(HDRHINT ${HDRHINT} "${dir}/${subdir}/libcaf_${comp}") endforeach() endforeach() find_path(LIBCAF_INCLUDE_DIR_${UPPERCOMP} NAMES ${HDRNAME} HINTS ${LIBCAF_ROOT_DIR}/include /usr/include /usr/local/include /opt/local/include /sw/include ${CMAKE_INSTALL_PREFIX}/include ${HDRHINT}) mark_as_advanced(LIBCAF_INCLUDE_DIR_${UPPERCOMP}) if (NOT "${LIBCAF_INCLUDE_DIR_${UPPERCOMP}}" STREQUAL "LIBCAF_INCLUDE_DIR_${UPPERCOMP}-NOTFOUND") # mark as found (set back to false in case library cannot be found) set(Libcaf_${comp}_FOUND true) # add to LIBCAF_INCLUDE_DIRS only if path isn't already set set(duplicate false) foreach (p ${LIBCAF_INCLUDE_DIRS}) if (${p} STREQUAL ${LIBCAF_INCLUDE_DIR_${UPPERCOMP}}) set(duplicate true) endif () endforeach () if (NOT duplicate) set(LIBCAF_INCLUDE_DIRS ${LIBCAF_INCLUDE_DIRS} ${LIBCAF_INCLUDE_DIR_${UPPERCOMP}}) endif() # look for (.dll|.so|.dylib) file, again giving hints for non-installed CAFs # skip probe_event as it is header only if (NOT ${comp} STREQUAL "probe_event") unset(LIBHINT) foreach(dir ".." "../.." "../../..") foreach(subdir "actor-framework" "caf") set(LIBHINT ${LIBHINT} "${dir}/${subdir}/build/lib") endforeach() endforeach() message(STATUS "libhint: ${LIBHINT}") find_library(LIBCAF_LIBRARY_${UPPERCOMP} NAMES "caf_${comp}" HINTS ${LIBCAF_ROOT_DIR}/lib ${LIBCAF_ROOT_DIR}/build/lib /usr/lib /usr/local/lib /opt/local/lib /sw/lib ${CMAKE_INSTALL_PREFIX}/lib ${LIBHINT}) mark_as_advanced(LIBCAF_LIBRARY_${UPPERCOMP}) if ("${LIBCAF_LIBRARY_${UPPERCOMP}}" STREQUAL "LIBCAF_LIBRARY-NOTFOUND") set(Libcaf_${comp}_FOUND false) else () set(LIBCAF_LIBRARIES ${LIBCAF_LIBRARIES} ${LIBCAF_LIBRARY_${UPPERCOMP}}) endif () endif () endif () endforeach () # let CMake check whether all requested components have been found include(FindPackageHandleStandardArgs) find_package_handle_standard_args(Libcaf FOUND_VAR LIBCAF_FOUND REQUIRED_VARS LIBCAF_LIBRARIES LIBCAF_INCLUDE_DIRS HANDLE_COMPONENTS) # final step to tell CMake we're done mark_as_advanced(LIBCAF_ROOT_DIR LIBCAF_LIBRARIES LIBCAF_INCLUDE_DIRS) actor-framework-0.13.2/cmake/FindOPENCL.cmake000066400000000000000000000016031251275671500205560ustar00rootroot00000000000000# - Try to find OpenCL # Once done this will define # # OpenCL_FOUND - system has OpenCL # OpenCL_INCLUDE_DIRS - the OpenCL include directory # OpenCL_LIBRARIES - link these to use OpenCL # # WIN32 should work, but is untested IF (WIN32) FIND_PATH(OpenCL_INCLUDE_DIRS CL/cl.h ) # TODO this is only a hack assuming the 64 bit library will # not be found on 32 bit system FIND_LIBRARY(OpenCL_LIBRARIES opencl ) #used to say opencl64 IF( OpenCL_LIBRARIES ) FIND_LIBRARY(OpenCL_LIBRARIES opencl ) #used to say opencl32 ENDIF( OpenCL_LIBRARIES ) ELSE (WIN32) FIND_LIBRARY(OpenCL_LIBRARIES OpenCL ENV LD_LIBRARY_PATH) message("-- Found OpenCL: ${OpenCL_LIBRARIES}") ENDIF (WIN32) SET( OpenCL_FOUND "NO" ) IF(OpenCL_LIBRARIES ) SET( OpenCL_FOUND "YES" ) ENDIF(OpenCL_LIBRARIES) MARK_AS_ADVANCED( OpenCL_INCLUDE_DIRS OpenCL_LIBRARIES ) actor-framework-0.13.2/cmake/cmake_uninstall.cmake.in000066400000000000000000000017631251275671500225620ustar00rootroot00000000000000if (NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") message(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"") endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) string(REGEX REPLACE "\n" ";" files "${files}") list(REVERSE files) foreach (file ${files}) message(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") if (EXISTS "$ENV{DESTDIR}${file}") execute_process( COMMAND @CMAKE_COMMAND@ -E remove "$ENV{DESTDIR}${file}" OUTPUT_VARIABLE rm_out RESULT_VARIABLE rm_retval ) if(NOT ${rm_retval} EQUAL 0) message(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") endif (NOT ${rm_retval} EQUAL 0) else (EXISTS "$ENV{DESTDIR}${file}") message(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.") endif (EXISTS "$ENV{DESTDIR}${file}") endforeach(file) actor-framework-0.13.2/cmake/get_compiler_version.cpp000066400000000000000000000004461251275671500227210ustar00rootroot00000000000000#include using namespace std; int main() { # ifdef __clang__ cout << __clang_major__ << "." << __clang_minor__; # elif defined(__GNUC__) cout << __GNUC__ << "." << __GNUC_MINOR__; # else cout << "0.0"; # endif return 0; } actor-framework-0.13.2/cmake/jenkins.cmake000066400000000000000000000010021251275671500204270ustar00rootroot00000000000000set(LABEL_EXPR "$ENV{label_exp}") if ("${LABEL_EXPR}" MATCHES "gcc") message(STATUS "Set CXX to g++ based on label_expr content") set(CMAKE_C_COMPILER "gcc" CACHE PATH "c++ compiler option") set(CMAKE_CXX_COMPILER "g++" CACHE PATH "c++ compiler option") elseif ("${LABEL_EXPR}" MATCHES "clang") message(STATUS "Set CXX to clang++ based on label_expr content") set(CMAKE_C_COMPILER "clang" CACHE STRING "c++ compiler option") set(CMAKE_CXX_COMPILER "clang++" CACHE STRING "c++ compiler option") endif() actor-framework-0.13.2/configure000077500000000000000000000312271251275671500166270ustar00rootroot00000000000000#!/bin/sh # Convenience wrapper for easily viewing/setting options that # the project's CMake scripts will recognize. # check for `cmake` command type cmake > /dev/null 2>&1 || { echo "\ This package requires CMake, please install it first, then you may use this configure script to access CMake equivalent functionality.\ " >&2; exit 1; } command="$0 $*" dirname_0=`dirname $0` sourcedir=`cd $dirname_0 && pwd` benchmark_suite_options="" if [ -d "$sourcedir/benchmarks/caf" ] ; then benchmark_suite_options="\ Benchmark Suite Options: --with-javac=FILE path to Java compiler --with-java=FILE path to Java Runtime --with-scalac=FILE path to Scala compiler --with-erlc=FILE path to Erlang compiler --with-charmc=FILE path to Charm++ compiler --with-salsa=FILE path to SALSA Lite jar " fi usage="\ Usage: $0 [OPTION]... [VAR=VALUE]... Build Options: --generator=GENERATOR set CMake generator (see cmake --help) --build-type=TYPE set CMake build type [RelWithDebInfo]: - Debug: debugging flags enabled - MinSizeRel: minimal output size - Release: optimizations on, debugging off - RelWithDebInfo: release flags plus debugging --build-dir=DIR place build files in directory [build] --bin-dir=DIR executable directory [build/bin] --lib-dir=DIR library directory [build/lib] --with-clang=FILE path to clang++ executable --with-gcc=FILE path to g++ executable --dual-build build using both gcc and clang --build-static build as static and shared library --build-static-only build as static library only --more-warnings enables most warnings --no-compiler-check disable compiler version check --no-auto-libc++ do not automatically enable libc++ for Clang --warnings-as-errors enables -Werror Installation Directories: --prefix=PREFIX installation directory [/usr/local] Remove Standard Features (even if all dependencies are available): --no-memory-management build without memory management --no-examples build without examples --no-qt-examples build without Qt examples --no-protobuf-examples build without Google Protobuf examples --no-curl-examples build without libcurl examples --no-unit-tests build without unit tests --no-opencl build without opencl --no-nexus build without nexus --no-cash build without cash --no-benchmarks build without benchmarks --no-riac build without riac Debugging: --with-runtime-checks build with requirement checks at runtime --with-log-level=LVL build with debugging output, possible values: - ERROR - WARNING - INFO - DEBUG - TRACE --with-address-sanitizer build with address sanitizer if available Influential Environment Variables (only on first invocation): CXX C++ compiler command CXXFLAGS C++ compiler flags iOS Build Options (should be used with XCode generator): --sysroot=DIR set system root for Clang - iphoneos: for iOS device - iphonesimulator: for iOS simulator --ios-min-ver=VERSION set the ios deployment target version $benchmark_suite_options" # Appends a CMake cache entry definition to the CMakeCacheEntries variable. # $1 is the cache entry variable name # $2 is the cache entry variable type # $3 is the cache entry variable value append_cache_entry () { case "$3" in *\ * ) # string contains whitespace CMakeCacheEntries="$CMakeCacheEntries -D \"$1:$2=$3\"" ;; *) # string contains whitespace CMakeCacheEntries="$CMakeCacheEntries -D $1:$2=$3" ;; esac } # Creates a build directory via CMake. # $1 is the path to a compiler executable. # $2 is the suffix of the build directory. # $3 is the executable output path. # $4 is the library output path. # $5 is the CMake generator. configure () { CMakeCacheEntries=$CMakeDefaultCache if [ -n "$1" ]; then append_cache_entry CMAKE_CXX_COMPILER FILEPATH $1 fi case "$builddir" in /*) #absolute path given absolute_builddir="$builddir" ;; *) # relative path given; convert to absolute path absolute_builddir="$PWD/$builddir" ;; esac if [ -n "$2" ]; then workdir="$absolute_builddir-$2" else workdir="$absolute_builddir" fi workdirs="$workdirs $workdir" if [ -n "$3" ]; then append_cache_entry EXECUTABLE_OUTPUT_PATH PATH "$3" else append_cache_entry EXECUTABLE_OUTPUT_PATH PATH "$workdir/bin" fi if [ -n "$4" ]; then append_cache_entry LIBRARY_OUTPUT_PATH PATH "$4" else append_cache_entry LIBRARY_OUTPUT_PATH PATH "$workdir/lib" fi if [ -d "$workdir" ]; then # If a build directory exists, check if it has a CMake cache. if [ -f "$workdir/CMakeCache.txt" ]; then # If the CMake cache exists, delete it so that this configuration # is not tainted by a previous one. rm -f "$workdir/CMakeCache.txt" fi else mkdir -p "$workdir" fi cd "$workdir" if [ -n "$5" ]; then cmake -G "$5" $CMakeCacheEntries "$sourcedir" else cmake $CMakeCacheEntries "$sourcedir" fi echo "# This is the command used to configure this build" > config.status if [ -n "$CC" ]; then printf "CC=%s" $CC >> config.status printf ' ' >> config.status fi if [ -n "$CXX" ]; then printf "CXX=%s" $CXX >> config.status printf ' ' >> config.status fi echo $command >> config.status chmod u+x config.status } # Set defaults. builddir="$sourcedir/build" CMakeCacheEntries="" append_cache_entry CMAKE_INSTALL_PREFIX PATH /usr/local append_cache_entry CAF_ENABLE_RUNTIME_CHECKS BOOL false # parse custom environment variable to initialize CMakeGenerator if [ -n "$DEFAULT_CMAKE_GENERATOR" ]; then CMakeGenerator="$DEFAULT_CMAKE_GENERATOR" fi # Parse arguments. while [ $# -ne 0 ]; do case "$1" in -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;; *) optarg= ;; esac case "$1" in --help|-h) echo "${usage}" 1>&2 exit 1 ;; --generator=*) CMakeGenerator="$optarg" ;; --prefix=*) append_cache_entry CMAKE_INSTALL_PREFIX PATH $optarg ;; --with-runtime-checks) append_cache_entry CAF_ENABLE_RUNTIME_CHECKS BOOL yes ;; --with-address-sanitizer) append_cache_entry ENABLE_ADDRESS_SANITIZER BOOL yes ;; --no-memory-management) append_cache_entry CAF_NO_MEM_MANAGEMENT BOOL yes ;; --more-warnings) append_cache_entry MORE_WARNINGS BOOL yes ;; --no-compiler-check) append_cache_entry NO_COMPILER_CHECK BOOL yes ;; --no-auto-libc++) append_cache_entry NO_AUTO_LIBCPP BOOL yes ;; --warnings-as-errors) append_cache_entry CXX_WARNINGS_AS_ERROS BOOL yes ;; --sysroot=*) append_cache_entry CAF_OSX_SYSROOT PATH "$optarg" ;; --ios-min-ver=*) append_cache_entry CMAKE_OSX_ARCHITECTURES STRING "\$(ARCHS_STANDARD_32_64_BIT)" append_cache_entry CAF_IOS_DEPLOYMENT_TARGET STRING "$optarg" ;; --with-log-level=*) level=`echo "$optarg" | tr '[:lower:]' '[:upper:]'` case $level in ERROR) append_cache_entry CAF_LOG_LEVEL STRING 0 ;; WARNING) append_cache_entry CAF_LOG_LEVEL STRING 1 ;; INFO) append_cache_entry CAF_LOG_LEVEL STRING 2 ;; DEBUG) append_cache_entry CAF_LOG_LEVEL STRING 3 ;; TRACE) append_cache_entry CAF_LOG_LEVEL STRING 4 ;; *) echo "Invalid log level '$level'. Try '$0 --help' to see valid values." exit 1 ;; esac ;; --with-clang=*) clang=$optarg ;; --with-gcc=*) gcc=$optarg ;; --build-type=*) append_cache_entry CMAKE_BUILD_TYPE STRING $optarg ;; --build-dir=*) builddir="$optarg" ;; --bin-dir=*) bindir="$optarg" ;; --lib-dir=*) libdir="$optarg" ;; --dual-build) dualbuild=1 ;; --no-examples) append_cache_entry CAF_NO_EXAMPLES BOOL yes ;; --no-qt-examples) append_cache_entry CAF_NO_QT_EXAMPLES BOOL yes ;; --no-protobuf-examples) append_cache_entry CAF_NO_PROTOBUF_EXAMPLES BOOL yes ;; --no-curl-examples) append_cache_entry CAF_NO_CURL_EXAMPLES BOOL yes ;; --no-unit-tests) append_cache_entry CAF_NO_UNIT_TESTS BOOL yes ;; --no-opencl) append_cache_entry CAF_NO_OPENCL BOOL yes ;; --build-static) append_cache_entry CAF_BUILD_STATIC BOOL yes ;; --build-static-only) append_cache_entry CAF_BUILD_STATIC_ONLY BOOL yes ;; --with-javac=*) append_cache_entry CAF_JAVA_COMPILER FILEPATH "$optarg" ;; --with-java=*) append_cache_entry CAF_JAVA_BIN FILEPATH "$optarg" ;; --with-scalac=*) append_cache_entry CAF_SCALA_COMPILER FILEPATH "$optarg" ;; --with-erlc=*) append_cache_entry CAF_ERLANG_COMPILER FILEPATH "$optarg" ;; --with-charmc=*) append_cache_entry CAF_CHARM_COMPILER FILEPATH "$optarg" ;; --with-salsa=*) append_cache_entry CAF_SALSA_JAR FILEPATH "$optarg" ;; --no-nexus) append_cache_entry CAF_NO_NEXUS BOOL yes ;; --no-cash) append_cache_entry CAF_NO_CASH BOOL yes ;; --no-benchmarks) append_cache_entry CAF_NO_BENCHMARKS BOOL yes ;; --no-riac) append_cache_entry CAF_NO_RIAC BOOL yes ;; *) echo "Invalid option '$1'. Try $0 --help to see available options." exit 1 ;; esac shift done # At this point we save the global CMake variables so that configure() can # later use them. CMakeDefaultCache=$CMakeCacheEntries if [ -n "$dualbuild" ]; then # Use what we got in $PATH if --with-clang or --with-gcc is not specified. if [ -z "$clang" ]; then clang=clang++ fi if [ -z "$gcc" ]; then gcc=g++ fi for i in gcc clang; do eval "compiler=\$$i" configure $compiler $i "" "" $CMakeGenerator done else # Prefer Clang to GCC. if [ -n "$clang" ]; then compiler=$clang elif [ -n "$gcc" ]; then compiler=$gcc fi configure "$compiler" "" "$bindir" "$libdir" "$CMakeGenerator" fi if [ -n "$CMakeGenerator" ] && [ "$CMakeGenerator" != "Unix" ]; then # skip Makefile-specific code below when not using make exit 0 fi printf "DIRS := %s\n\n" "$workdirs" > $sourcedir/Makefile makefile=`cat <<'EOT' all: @for i in $(DIRS); do $(MAKE) -C $$i $@ || exit; done test: @for i in $(DIRS); do $(MAKE) -C $$i $@ || exit; done install: @for i in $(DIRS); do $(MAKE) -C $$i $@ || exit; done uninstall: @for i in $(DIRS); do $(MAKE) -C $$i $@ || exit; done clean: @for i in $(DIRS); do $(MAKE) -C $$i $@; done distclean: rm -rf $(DIRS) Makefile doc: $(MAKE) -C $(firstword $(DIRS)) $@ .PHONY: all test install uninstall clean distclean EOT ` echo "$makefile" >> $sourcedir/Makefile actor-framework-0.13.2/examples/000077500000000000000000000000001251275671500165315ustar00rootroot00000000000000actor-framework-0.13.2/examples/CMakeLists.txt000066400000000000000000000104331251275671500212720ustar00rootroot00000000000000cmake_minimum_required(VERSION 2.8) project(caf_examples CXX) add_custom_target(all_examples) include_directories(${LIBCAF_INCLUDE_DIRS}) if(${CMAKE_SYSTEM_NAME} MATCHES "Window") set(WSLIB -lws2_32) else () set(WSLIB) endif() macro(add name folder) add_executable(${name} ${folder}/${name}.cpp ${ARGN}) target_link_libraries(${name} ${LD_FLAGS} ${LIBCAF_LIBRARIES} ${PTHREAD_LIBRARIES} ${WSLIB}) install(FILES ${folder}/${name}.cpp DESTINATION share/caf/examples/${folder}) add_dependencies(${name} all_examples) endmacro() add(announce_1 type_system) add(announce_2 type_system) add(announce_3 type_system) add(announce_4 type_system) add(announce_5 type_system) add(dancing_kirby message_passing) add(dining_philosophers message_passing) add(hello_world .) add(aout .) add(calculator message_passing) add(typed_calculator message_passing) add(distributed_calculator remote_actors) add(group_server remote_actors) add(group_chat remote_actors) add(simple_broker brokers) add(simple_http_broker brokers) if(NOT CAF_NO_PROTOBUF_EXAMPLES) find_package(Protobuf) if(PROTOBUF_FOUND AND PROTOBUF_PROTOC_EXECUTABLE) PROTOBUF_GENERATE_CPP(ProtoSources ProtoHeaders "${CMAKE_CURRENT_SOURCE_DIR}/remote_actors/pingpong.proto") include_directories(${PROTOBUF_INCLUDE_DIR}) # add binary dir as include path as generated headers will be located there include_directories(${CMAKE_CURRENT_BINARY_DIR}) add_executable(protobuf_broker brokers/protobuf_broker.cpp ${ProtoSources}) target_link_libraries(protobuf_broker ${CMAKE_DL_LIBS} ${LIBCAF_LIBRARIES} ${PTHREAD_LIBRARIES} ${PROTOBUF_LIBRARIES}) add_dependencies(protobuf_broker all_examples) endif(PROTOBUF_FOUND AND PROTOBUF_PROTOC_EXECUTABLE) endif() if(NOT CAF_NO_QT_EXAMPLES) find_package(Qt5 COMPONENTS Core Gui Widgets) if(Qt5_FOUND) message(STATUS "Found Qt5") #include(${QT_USE_FILE}) QT5_ADD_RESOURCES(GROUP_CHAT_RCS ) QT5_WRAP_UI(GROUP_CHAT_UI_HDR qtsupport/chatwindow.ui) QT5_WRAP_CPP(GROUP_CHAT_MOC_SRC qtsupport/chatwidget.hpp) # generated headers will be in cmake build directory #include_directories(. qtsupport ${CMAKE_CURRENT_BINARY_DIR} ${CPPA_INCLUDE}) include_directories(qtsupport ${CMAKE_CURRENT_BINARY_DIR} ${Qt5Core_INCLUDE_DIRS} ${Qt5Gui_INCLUDE_DIRS} ${Qt5Widgets_INCLUDE_DIRS}) set(GROUP_CHAT_SRC qtsupport/qt_group_chat.cpp qtsupport/chatwidget.cpp) add_executable(qt_group_chat ${GROUP_CHAT_SRC} ${GROUP_CHAT_MOC_SRC} ${GROUP_CHAT_UI_HDR}) target_link_libraries(qt_group_chat ${CMAKE_DL_LIBS} ${LIBCAF_LIBRARIES} Qt5::Core Qt5::Gui Qt5::Widgets) add_dependencies(qt_group_chat all_examples) else() find_package(Qt4) if(QT4_FOUND) message(STATUS "Found Qt4") include(${QT_USE_FILE}) QT4_ADD_RESOURCES(GROUP_CHAT_RCS ) QT4_WRAP_UI(GROUP_CHAT_UI_HDR qtsupport/chatwindow.ui) QT4_WRAP_CPP(GROUP_CHAT_MOC_SRC qtsupport/chatwidget.hpp) # generated headers will be in cmake build directory #include_directories(. qtsupport ${CMAKE_CURRENT_BINARY_DIR} ${CPPA_INCLUDE}) include_directories(qtsupport ${CMAKE_CURRENT_BINARY_DIR}) set(GROUP_CHAT_SRCS qtsupport/qt_group_chat.cpp qtsupport/chatwidget.cpp) add_executable(qt_group_chat ${GROUP_CHAT_SRCS} ${GROUP_CHAT_MOC_SRC} ${GROUP_CHAT_UI_HDR}) target_link_libraries(qt_group_chat ${CMAKE_DL_LIBS} ${LIBCAF_LIBRARIES} ${QT_LIBRARIES}) add_dependencies(qt_group_chat all_examples) endif() endif() endif() if(NOT CAF_NO_CURL_EXAMPLES) find_package(CURL) if(CURL_FOUND) add_executable(curl_fuse curl/curl_fuse.cpp) include_directories(${CURL_INCLUDE_DIRS}) target_link_libraries(curl_fuse ${CMAKE_DL_LIBS} ${LIBCAF_LIBRARIES} ${PTHREAD_LIBRARIES} ${CURL_LIBRARY}) add_dependencies(curl_fuse all_examples) endif(CURL_FOUND) endif() actor-framework-0.13.2/examples/aout.cpp000066400000000000000000000017631251275671500202140ustar00rootroot00000000000000/******************************************************************************\ * This example illustrates how to use aout. * \******************************************************************************/ #include #include #include #include #include "caf/all.hpp" using namespace caf; using std::endl; int main() { for (int i = 1; i <= 50; ++i) { spawn([i](blocking_actor* self) { aout(self) << "Hi there! This is actor nr. " << i << "!" << endl; std::random_device rd; std::default_random_engine re(rd()); std::chrono::milliseconds tout{re() % 10}; self->delayed_send(self, tout, 42); self->receive( [i, self](int) { aout(self) << "Actor nr. " << i << " says goodbye!" << endl; } ); }); } // wait until all other actors we've spawned are done await_all_actors_done(); // done shutdown(); } actor-framework-0.13.2/examples/brokers/000077500000000000000000000000001251275671500202005ustar00rootroot00000000000000actor-framework-0.13.2/examples/brokers/protobuf_broker.cpp000066400000000000000000000122101251275671500241040ustar00rootroot00000000000000#include #include #include #include #include #include #include "caf/all.hpp" #include "caf/io/all.hpp" CAF_PUSH_WARNINGS #include "pingpong.pb.h" CAF_POP_WARNINGS using namespace std; using namespace caf; using namespace caf::io; void print_on_exit(const actor& ptr, const std::string& name) { ptr->attach_functor([=](std::uint32_t reason) { aout(ptr) << name << " exited with reason " << reason << endl; }); } behavior ping(event_based_actor* self, size_t num_pings) { auto count = make_shared(0); return { on(atom("kickoff"), arg_match) >> [=](const actor& pong) { self->send(pong, atom("ping"), 1); self->become ( on(atom("pong"), arg_match) >> [=](int value) -> message { if (++*count >= num_pings) self->quit(); return make_message(atom("ping"), value + 1); } ); } }; } behavior pong() { return { on(atom("ping"), arg_match) >> [](int value) { return make_message(atom("pong"), value); } }; } void protobuf_io(broker* self, connection_handle hdl, const actor& buddy) { self->monitor(buddy); auto write = [=](const org::libcppa::PingOrPong& p) { string buf = p.SerializeAsString(); int32_t s = htonl(static_cast(buf.size())); self->write(hdl, sizeof(int32_t), &s); self->write(hdl, buf.size(), buf.data()); self->flush(hdl); }; message_handler default_bhvr = { [=](const connection_closed_msg&) { aout(self) << "connection closed" << endl; self->send_exit(buddy, exit_reason::remote_link_unreachable); self->quit(exit_reason::remote_link_unreachable); }, on(atom("ping"), arg_match) >> [=](int i) { aout(self) << "'ping' " << i << endl; org::libcppa::PingOrPong p; p.mutable_ping()->set_id(i); write(p); }, on(atom("pong"), arg_match) >> [=](int i) { aout(self) << "'pong' " << i << endl; org::libcppa::PingOrPong p; p.mutable_pong()->set_id(i); write(p); }, [=](const down_msg& dm) { if (dm.source == buddy) { aout(self) << "our buddy is down" << endl; self->quit(dm.reason); } }, others >> [=] { cout << "unexpected: " << to_string(self->current_message()) << endl; } }; auto await_protobuf_data = message_handler { [=](const new_data_msg& msg) { org::libcppa::PingOrPong p; p.ParseFromArray(msg.buf.data(), static_cast(msg.buf.size())); if (p.has_ping()) { self->send(buddy, atom("ping"), p.ping().id()); } else if (p.has_pong()) { self->send(buddy, atom("pong"), p.pong().id()); } else { self->quit(exit_reason::user_shutdown); cerr << "neither Ping nor Pong!" << endl; } // receive next length prefix self->configure_read(hdl, receive_policy::exactly(sizeof(int32_t))); self->unbecome(); } }.or_else(default_bhvr); auto await_length_prefix = message_handler { [=](const new_data_msg& msg) { int32_t num_bytes; memcpy(&num_bytes, msg.buf.data(), sizeof(int32_t)); num_bytes = htonl(num_bytes); if (num_bytes < 0 || num_bytes > (1024 * 1024)) { aout(self) << "someone is trying something nasty" << endl; self->quit(exit_reason::user_shutdown); return; } // receive protobuf data auto nb = static_cast(num_bytes); self->configure_read(hdl, receive_policy::exactly(nb)); self->become(keep_behavior, await_protobuf_data); } }.or_else(default_bhvr); // initial setup self->configure_read(hdl, receive_policy::exactly(sizeof(int32_t))); self->become(await_length_prefix); } behavior server(broker* self, actor buddy) { aout(self) << "server is running" << endl; return { [=](const new_connection_msg& msg) { aout(self) << "server accepted new connection" << endl; auto io_actor = self->fork(protobuf_io, msg.handle, buddy); print_on_exit(io_actor, "protobuf_io"); // only accept 1 connection in our example self->quit(); }, others >> [=] { cout << "unexpected: " << to_string(self->current_message()) << endl; } }; } optional as_u16(const std::string& str) { return static_cast(stoul(str)); } int main(int argc, char** argv) { message_builder{argv + 1, argv + argc}.apply({ on("-s", as_u16) >> [&](uint16_t port) { cout << "run in server mode" << endl; auto pong_actor = spawn(pong); auto sever_actor = spawn_io_server(server, port, pong_actor); print_on_exit(sever_actor, "server"); print_on_exit(pong_actor, "pong"); }, on("-c", val, as_u16) >> [&](const string& host, uint16_t port) { auto ping_actor = spawn(ping, 20); auto io_actor = spawn_io_client(protobuf_io, host, port, ping_actor); print_on_exit(io_actor, "protobuf_io"); print_on_exit(ping_actor, "ping"); send_as(io_actor, ping_actor, atom("kickoff"), io_actor); }, others >> [] { cerr << "use with eihter '-s PORT' as server or " "'-c HOST PORT' as client" << endl; } }); await_all_actors_done(); shutdown(); } actor-framework-0.13.2/examples/brokers/simple_broker.cpp000066400000000000000000000157771251275671500235620ustar00rootroot00000000000000/******************************************************************************\ * This example program showcases how to manually manage socket IO using * * a broker. Server and client exchange integers in a 'ping-pong protocol'. * * * * Minimal setup: * * - ./build/bin/broker -s 4242 * * - ./build/bin/broker -c localhost 4242 * \ ******************************************************************************/ #ifdef WIN32 # define _WIN32_WINNT 0x0600 # include #else # include // htonl #endif #include #include #include #include #include #include #include #include "caf/all.hpp" #include "caf/io/all.hpp" using std::cout; using std::cerr; using std::endl; using namespace caf; using namespace caf::io; using ping_atom = atom_constant; using pong_atom = atom_constant; using kickoff_atom = atom_constant; // utility function to print an exit message with custom name void print_on_exit(const actor& ptr, const std::string& name) { ptr->attach_functor([=](uint32_t reason) { aout(ptr) << name << " exited with reason " << reason << endl; }); } behavior ping(event_based_actor* self, size_t num_pings) { auto count = std::make_shared(0); return { [=](kickoff_atom, const actor& pong) { self->send(pong, ping_atom::value, int32_t(1)); self->become ( [=](pong_atom, int32_t value) -> message { if (++*count >= num_pings) self->quit(); return make_message(ping_atom::value, value + 1); } ); } }; } behavior pong() { return { [](ping_atom, int32_t value) { return make_message(pong_atom::value, value); } }; } // utility function for sending an integer type template void write_int(broker* self, connection_handle hdl, T value) { using unsigned_type = typename std::make_unsigned::type; auto cpy = static_cast(htonl(static_cast(value))); self->write(hdl, sizeof(T), &cpy); self->flush(hdl); } void write_int(broker* self, connection_handle hdl, uint64_t value) { // write two uint32 values instead (htonl does not work for 64bit integers) write_int(self, hdl, static_cast(value)); write_int(self, hdl, static_cast(value >> sizeof(uint32_t))); } // utility function for reading an ingeger from incoming data template void read_int(const void* data, T& storage) { using unsigned_type = typename std::make_unsigned::type; memcpy(&storage, data, sizeof(T)); storage = static_cast(ntohl(static_cast(storage))); } void read_int(const void* data, uint64_t& storage) { uint32_t first; uint32_t second; read_int(data, first); read_int(reinterpret_cast(data) + sizeof(uint32_t), second); storage = first | (static_cast(second) << sizeof(uint32_t)); } // implemenation of our broker behavior broker_impl(broker* self, connection_handle hdl, const actor& buddy) { // we assume io_fsm manages a broker with exactly one connection, // i.e., the connection ponted to by `hdl` assert(self->num_connections() == 1); // monitor buddy to quit broker if buddy is done self->monitor(buddy); // setup: we are exchanging only messages consisting of an atom // (as uint64_t) and an integer value (int32_t) self->configure_read(hdl, receive_policy::exactly(sizeof(uint64_t) + sizeof(int32_t))); // our message handlers return { [=](const connection_closed_msg& msg) { // brokers can multiplex any number of connections, however // this example assumes io_fsm to manage a broker with // exactly one connection if (msg.handle == hdl) { aout(self) << "connection closed" << endl; // force buddy to quit self->send_exit(buddy, exit_reason::remote_link_unreachable); self->quit(exit_reason::remote_link_unreachable); } }, [=](atom_value av, int32_t i) { assert(av == ping_atom::value || av == pong_atom::value); aout(self) << "send {" << to_string(av) << ", " << i << "}" << endl; // cast atom to its underlying type, i.e., uint64_t write_int(self, hdl, static_cast(av)); write_int(self, hdl, i); }, [=](const down_msg& dm) { if (dm.source == buddy) { aout(self) << "our buddy is down" << endl; // quit for same reason self->quit(dm.reason); } }, [=](const new_data_msg& msg) { // read the atom value as uint64_t from buffer uint64_t atm_val; read_int(msg.buf.data(), atm_val); // cast to original type auto atm = static_cast(atm_val); // read integer value from buffer, jumping to the correct // position via offset_data(...) int32_t ival; read_int(msg.buf.data() + sizeof(uint64_t), ival); // show some output aout(self) << "received {" << to_string(atm) << ", " << ival << "}" << endl; // send composed message to our buddy self->send(buddy, atm, ival); }, others >> [=] { aout(self) << "unexpected: " << to_string(self->current_message()) << endl; } }; } behavior server(broker* self, const actor& buddy) { aout(self) << "server is running" << endl; return { [=](const new_connection_msg& msg) { aout(self) << "server accepted new connection" << endl; // by forking into a new broker, we are no longer // responsible for the connection auto impl = self->fork(broker_impl, msg.handle, buddy); print_on_exit(impl, "broker_impl"); aout(self) << "quit server (only accept 1 connection)" << endl; self->quit(); }, others >> [=] { aout(self) << "unexpected: " << to_string(self->current_message()) << endl; } }; } optional as_u16(const std::string& str) { return static_cast(stoul(str)); } int main(int argc, char** argv) { using std::string; message_builder{argv + 1, argv + argc}.apply({ on("-s", as_u16) >> [&](uint16_t port) { cout << "run in server mode" << endl; auto pong_actor = spawn(pong); auto server_actor = spawn_io_server(server, port, pong_actor); print_on_exit(server_actor, "server"); print_on_exit(pong_actor, "pong"); }, on("-c", val, as_u16) >> [&](const string& host, uint16_t port) { auto ping_actor = spawn(ping, 20); auto io_actor = spawn_io_client(broker_impl, host, port, ping_actor); print_on_exit(io_actor, "protobuf_io"); print_on_exit(ping_actor, "ping"); send_as(io_actor, ping_actor, kickoff_atom::value, io_actor); }, others >> [] { cerr << "use with eihter '-s PORT' as server or '-c HOST PORT' as client" << endl; } }); await_all_actors_done(); shutdown(); } actor-framework-0.13.2/examples/brokers/simple_http_broker.cpp000066400000000000000000000043141251275671500246020ustar00rootroot00000000000000#include #include #include "caf/all.hpp" #include "caf/io/all.hpp" using std::cout; using std::cerr; using std::endl; using namespace caf; using namespace caf::io; using tick_atom = atom_constant; const char http_ok[] = R"__(HTTP/1.1 200 OK Content-Type: text/plain Connection: keep-alive Transfer-Encoding: chunked d Hi there! :) 0 )__"; template constexpr size_t cstr_size(const char (&)[Size]) { return Size; } behavior connection_worker(broker* self, connection_handle hdl) { self->configure_read(hdl, receive_policy::at_most(1024)); return { [=](const new_data_msg& msg) { self->write(msg.handle, cstr_size(http_ok), http_ok); self->quit(); }, [=](const connection_closed_msg&) { self->quit(); } }; } behavior server(broker* self) { auto counter = std::make_shared(0); self->delayed_send(self, std::chrono::seconds(1), tick_atom::value); return { [=](const new_connection_msg& ncm) { auto worker = self->fork(connection_worker, ncm.handle); self->monitor(worker); self->link_to(worker); }, [=](const down_msg&) { ++*counter; }, [=](tick_atom) { aout(self) << "Finished " << *counter << " requests per second." << endl; *counter = 0; self->delayed_send(self, std::chrono::seconds(1), tick_atom::value); }, others >> [=] { aout(self) << "unexpected: " << to_string(self->current_message()) << endl; } }; } optional as_u16(const std::string& str) { return static_cast(stoul(str)); } int main(int argc, const char **argv) { message_builder{argv + 1, argv + argc}.apply({ on("-p", as_u16) >> [&](uint16_t port) { cout << "*** run in server mode listen on: " << port << endl; cout << "*** to quit the program, simply press " << endl; auto server_actor = spawn_io_server(server, port); // wait for any input std::string dummy; std::getline(std::cin, dummy); // kill server anon_send_exit(server_actor, exit_reason::user_shutdown); }, others >> [] { cerr << "use with '-p PORT' as server on port" << endl; } }); await_all_actors_done(); shutdown(); } actor-framework-0.13.2/examples/curl/000077500000000000000000000000001251275671500174765ustar00rootroot00000000000000actor-framework-0.13.2/examples/curl/curl_fuse.cpp000066400000000000000000000321141251275671500221720ustar00rootroot00000000000000/******************************************************************************\ * This example * * - emulates a client launching a request every 10-300ms * * - uses a CURL-backend consisting of a master and 10 workers * * - runs until it is shut down by a CTRL+C signal * * * * * * Schematic view: * * * * client | client_job | curl_master | curl_worker * * /--------------|*|-------------\ /-------------|*| * * /---------------|*|--------------\ / * * /----------------|*|---------------\ / * * |*| ----------------|*|----------------|*|----------------|*| * * \________________|*|_______________/ \ * * \_______________|*|______________/ \ * * \______________|*|_____________/ \-------------|*| * * * * * * Communication pattern: * * * * client_job curl_master curl_worker * * | | | * * | ----(read)-----> | | * * | | --(forward)----> | * * | |---\ * * | | | * * | |<--/ * * | <-------------(reply)-------------- | * * X * \ ******************************************************************************/ // C includes #include #include #include // C++ includes #include #include #include #include // libcurl #include // libcaf #include "caf/all.hpp" // disable some clang warnings here caused by CURL #ifdef __clang__ # pragma clang diagnostic ignored "-Wshorten-64-to-32" # pragma clang diagnostic ignored "-Wdisabled-macro-expansion" # pragma clang diagnostic ignored "-Wunused-const-variable" #endif // __clang__ using namespace caf; using buffer_type = std::vector; using read_atom = atom_constant; using fail_atom = atom_constant; using next_atom = atom_constant; using reply_atom = atom_constant; using finished_atom = atom_constant; namespace color { // UNIX terminal color codes constexpr char reset[] = "\033[0m"; constexpr char reset_endl[] = "\033[0m\n"; constexpr char black[] = "\033[30m"; constexpr char red[] = "\033[31m"; constexpr char green[] = "\033[32m"; constexpr char yellow[] = "\033[33m"; constexpr char blue[] = "\033[34m"; constexpr char magenta[] = "\033[35m"; constexpr char cyan[] = "\033[36m"; constexpr char white[] = "\033[37m"; constexpr char bold_black[] = "\033[1m\033[30m"; constexpr char bold_red[] = "\033[1m\033[31m"; constexpr char bold_green[] = "\033[1m\033[32m"; constexpr char bold_yellow[] = "\033[1m\033[33m"; constexpr char bold_blue[] = "\033[1m\033[34m"; constexpr char bold_magenta[] = "\033[1m\033[35m"; constexpr char bold_cyan[] = "\033[1m\033[36m"; constexpr char bold_white[] = "\033[1m\033[37m"; } // namespace color // number of HTTP workers constexpr size_t num_curl_workers = 10; // minimum delay between HTTP requests constexpr int min_req_interval = 10; // maximum delay between HTTP requests constexpr int max_req_interval = 300; // provides print utility and each base_actor has a parent class base_actor : public event_based_actor { protected: base_actor(actor parent, std::string name, std::string color_code) : m_parent(std::move(parent)), m_name(std::move(name)), m_color(std::move(color_code)), m_out(this) { // nop } ~base_actor(); inline actor_ostream& print() { return m_out << m_color << m_name << " (id = " << id() << "): "; } void on_exit() { print() << "on_exit" << color::reset_endl; } actor m_parent; private: std::string m_name; std::string m_color; actor_ostream m_out; }; base_actor::~base_actor() { // avoid weak-vtables warning } // encapsulates an HTTP request class client_job : public base_actor { public: client_job(actor parent) : base_actor(std::move(parent), "client_job", color::blue) { // nop } ~client_job(); protected: behavior make_behavior() override { print() << "init" << color::reset_endl; send(m_parent, read_atom::value, "http://www.example.com/index.html", uint64_t{0}, uint64_t{4095}); return { [=](reply_atom, const buffer_type& buf) { print() << "successfully received " << buf.size() << " bytes" << color::reset_endl; quit(); }, [=](fail_atom) { print() << "failure" << color::reset_endl; quit(); } }; } }; client_job::~client_job() { // avoid weak-vtables warning } // spawns HTTP requests class client : public base_actor { public: client(const actor& parent) : base_actor(parent, "client", color::green), m_count(0), m_re(m_rd()), m_dist(min_req_interval, max_req_interval) { // nop } ~client(); protected: behavior make_behavior() override { using std::chrono::milliseconds; link_to(m_parent); print() << "init" << color::reset_endl; // start 'loop' send(this, next_atom::value); return ( [=](next_atom) { print() << "spawn new client_job (nr. " << ++m_count << ")" << color::reset_endl; // client_job will use IO // and should thus be spawned in a separate thread spawn(m_parent); // compute random delay until next job is launched auto delay = m_dist(m_re); delayed_send(this, milliseconds(delay), next_atom::value); } ); } private: size_t m_count; std::random_device m_rd; std::default_random_engine m_re; std::uniform_int_distribution m_dist; }; client::~client() { // avoid weak-vtables warning } // manages a CURL session class curl_worker : public base_actor { public: curl_worker(const actor& parent) : base_actor(parent, "curl_worker", color::yellow), m_curl(nullptr) { // nop } ~curl_worker(); protected: behavior make_behavior() override { print() << "init" << color::reset_endl; m_curl = curl_easy_init(); curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, &curl_worker::cb); curl_easy_setopt(m_curl, CURLOPT_NOSIGNAL, 1); return ( [=](read_atom, const std::string& fname, uint64_t offset, uint64_t range) -> message { print() << "read" << color::reset_endl; for (;;) { m_buf.clear(); // set URL curl_easy_setopt(m_curl, CURLOPT_URL, fname.c_str()); // set range std::ostringstream oss; oss << offset << "-" << range; curl_easy_setopt(m_curl, CURLOPT_RANGE, oss.str().c_str()); // set curl callback curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, reinterpret_cast(this)); // launch file transfer auto res = curl_easy_perform(m_curl); if (res != CURLE_OK) { print() << "curl_easy_perform() failed: " << curl_easy_strerror(res) << color::reset_endl; } else { long hc = 0; // http return code curl_easy_getinfo(m_curl, CURLINFO_RESPONSE_CODE, &hc); switch (hc) { default: print() << "http error: download failed with " << "'HTTP RETURN CODE': " << hc << color::reset_endl; break; case 200: // ok case 206: // partial content print() << "received " << m_buf.size() << " bytes with 'HTTP RETURN CODE': " << hc << color::reset_endl; // tell parent that this worker is done send(m_parent, finished_atom::value); return make_message(reply_atom::value, m_buf); case 404: // file does not exist print() << "http error: download failed with " << "'HTTP RETURN CODE': 404 (file does " << "not exist!)" << color::reset_endl; } } // avoid 100% cpu utilization if remote side is not accessible std::this_thread::sleep_for(std::chrono::milliseconds(100)); } } ); } void on_exit() { curl_easy_cleanup(m_curl); print() << "on_exit" << color::reset_endl; } private: static size_t cb(void* data, size_t bsize, size_t nmemb, void* userp) { size_t size = bsize * nmemb; auto& buf = reinterpret_cast(userp)->m_buf; auto first = reinterpret_cast(data); auto last = first + bsize; buf.insert(buf.end(), first, last); return size; } CURL* m_curl; buffer_type m_buf; }; curl_worker::~curl_worker() { // avoid weak-vtables warning } // manages {num_curl_workers} workers with a round-robin protocol class curl_master : public base_actor { public: curl_master() : base_actor(invalid_actor, "curl_master", color::magenta) { // nop } ~curl_master(); protected: behavior make_behavior() override { print() << "init" << color::reset_endl; // spawn workers for(size_t i = 0; i < num_curl_workers; ++i) { m_idle_worker.push_back(spawn(this)); } auto worker_finished = [=] { auto sender = current_sender(); auto i = std::find(m_busy_worker.begin(), m_busy_worker.end(), sender); m_idle_worker.push_back(*i); m_busy_worker.erase(i); print() << "worker is done" << color::reset_endl; }; print() << "spawned " << m_idle_worker.size() << " worker(s)" << color::reset_endl; return { [=](read_atom, const std::string&, uint64_t, uint64_t) { print() << "received {'read'}" << color::reset_endl; // forward job to an idle worker actor worker = m_idle_worker.back(); m_idle_worker.pop_back(); m_busy_worker.push_back(worker); forward_to(worker); print() << m_busy_worker.size() << " active jobs" << color::reset_endl; if (m_idle_worker.empty()) { // wait until at least one worker finished its job become ( keep_behavior, [=](finished_atom) { worker_finished(); unbecome(); } ); } }, [=](finished_atom) { worker_finished(); } }; } private: std::vector m_idle_worker; std::vector m_busy_worker; }; curl_master::~curl_master() { // avoid weak-vtables warning } // signal handling for ctrl+c namespace { std::atomic shutdown_flag{false}; } // namespace int main() { // random number setup // install signal handler struct sigaction act; act.sa_handler = [](int) { shutdown_flag = true; }; auto set_sighandler = [&] { if (sigaction(SIGINT, &act, 0)) { std::cerr << "fatal: cannot set signal handler" << std::endl; abort(); } }; set_sighandler(); // initialize CURL curl_global_init(CURL_GLOBAL_DEFAULT); { // lifetime scope of self scoped_actor self; // spawn client and curl_master auto master = self->spawn(); self->spawn(master); // poll CTRL+C flag every second while (!shutdown_flag) { std::this_thread::sleep_for(std::chrono::seconds(1)); } aout(self) << color::cyan << "received CTRL+C" << color::reset_endl; // shutdown actors anon_send_exit(master, exit_reason::user_shutdown); // await actors act.sa_handler = [](int) { abort(); }; set_sighandler(); aout(self) << color::cyan << "await CURL; this may take a while " "(press CTRL+C again to abort)" << color::reset_endl; self->await_all_other_actors_done(); } // shutdown libcaf shutdown(); // shutdown CURL curl_global_cleanup(); } actor-framework-0.13.2/examples/hello_world.cpp000066400000000000000000000023551251275671500215540ustar00rootroot00000000000000#include #include #include "caf/all.hpp" using std::endl; using std::string; using namespace caf; behavior mirror(event_based_actor* self) { // return the (initial) actor behavior return { // a handler for messages containing a single string // that replies with a string [=](const string& what) -> string { // prints "Hello World!" via aout (thread-safe cout wrapper) aout(self) << what << endl; // terminates this actor ('become' otherwise loops forever) self->quit(); // reply "!dlroW olleH" return string(what.rbegin(), what.rend()); } }; } void hello_world(event_based_actor* self, const actor& buddy) { // send "Hello World!" to our buddy ... self->sync_send(buddy, "Hello World!").then( // ... wait for a response ... [=](const string& what) { // ... and print it aout(self) << what << endl; } ); } int main() { // create a new actor that calls 'mirror()' auto mirror_actor = spawn(mirror); // create another actor that calls 'hello_world(mirror_actor)'; spawn(hello_world, mirror_actor); // wait until all other actors we have spawned are done await_all_actors_done(); // run cleanup code before exiting main shutdown(); } actor-framework-0.13.2/examples/message_passing/000077500000000000000000000000001251275671500217015ustar00rootroot00000000000000actor-framework-0.13.2/examples/message_passing/calculator.cpp000066400000000000000000000042441251275671500245420ustar00rootroot00000000000000/******************************************************************************\ * This example is a very basic, non-interactive math service implemented * * for both the blocking and the event-based API. * \ ******************************************************************************/ #include #include #include #include "caf/all.hpp" using std::cout; using std::endl; using namespace caf; using plus_atom = atom_constant; using minus_atom = atom_constant; // implementation using the blocking API void blocking_calculator(blocking_actor* self) { self->receive_loop ( [](plus_atom, int a, int b) { return a + b; }, [](minus_atom, int a, int b) { return a - b; }, others >> [=] { cout << "unexpected: " << to_string(self->current_message()) << endl; } ); } // execute this behavior until actor terminates behavior calculator(event_based_actor* self) { return behavior{ [](plus_atom, int a, int b) { return a + b; }, [](minus_atom, int a, int b) { return a - b; }, others >> [=] { cout << "unexpected: " << to_string(self->current_message()) << endl; } }; } void tester(event_based_actor* self, const actor& testee) { self->link_to(testee); // will be invoked if we receive an unexpected response message self->on_sync_failure([=] { aout(self) << "AUT (actor under test) failed" << endl; self->quit(exit_reason::user_shutdown); }); // first test: 2 + 1 = 3 self->sync_send(testee, plus_atom::value, 2, 1).then( on(3) >> [=] { // second test: 2 - 1 = 1 self->sync_send(testee, minus_atom::value, 2, 1).then( on(1) >> [=] { // both tests succeeded aout(self) << "AUT (actor under test) seems to be ok" << endl; self->quit(exit_reason::user_shutdown); } ); } ); } int main() { cout << "test blocking actor" << endl; spawn(tester, spawn(blocking_calculator)); await_all_actors_done(); cout << "test event-based actor" << endl; spawn(tester, spawn(calculator)); await_all_actors_done(); shutdown(); } actor-framework-0.13.2/examples/message_passing/dancing_kirby.cpp000066400000000000000000000041521251275671500252120ustar00rootroot00000000000000/******************************************************************************\ * This example illustrates how to do time-triggered loops in libcaf. * \ ******************************************************************************/ #include #include #include #include "caf/all.hpp" using std::cout; using std::endl; using std::pair; using namespace caf; using step_atom = atom_constant; // ASCII art figures constexpr const char* figures[] = { "<(^.^<)", "<(^.^)>", "(>^.^)>" }; struct animation_step { size_t figure_idx; size_t offset; }; // array of {figure, offset} pairs constexpr animation_step animation_steps[] = { {1, 7}, {0, 7}, {0, 6}, {0, 5}, {1, 5}, {2, 5}, {2, 6}, {2, 7}, {2, 8}, {2, 9}, {2, 10}, {1, 10}, {0, 10}, {0, 9}, {1, 9}, {2, 10}, {2, 11}, {2, 12}, {2, 13}, {1, 13}, {0, 13}, {0, 12}, {0, 11}, {0, 10}, {0, 9}, {0, 8}, {0, 7}, {1, 7} }; constexpr size_t animation_width = 20; // "draws" an animation step by printing "{offset_whitespaces}{figure}{padding}" void draw_kirby(const animation_step& animation) { cout.width(animation_width); // override last figure cout << '\r'; // print offset std::fill_n(std::ostream_iterator{cout}, animation.offset, ' '); // print figure cout << figures[animation.figure_idx]; // print padding cout.fill(' '); // make sure figure is printed cout.flush(); } // uses a message-based loop to iterate over all animation steps void dancing_kirby(event_based_actor* self) { // let's get it started self->send(self, step_atom::value, size_t{0}); self->become ( [=](step_atom, size_t step) { if (step == sizeof(animation_step)) { // we've printed all animation steps (done) cout << endl; self->quit(); return; } // print given step draw_kirby(animation_steps[step]); // animate next step in 150ms self->delayed_send(self, std::chrono::milliseconds(150), step_atom::value, step + 1); } ); } int main() { spawn(dancing_kirby); await_all_actors_done(); shutdown(); } actor-framework-0.13.2/examples/message_passing/dining_philosophers.cpp000066400000000000000000000144641251275671500264650ustar00rootroot00000000000000/******************************************************************************\ * This example is an implementation of the classical Dining Philosophers * * exercise using only libcaf's event-based actor implementation. * \ ******************************************************************************/ #include #include #include #include #include #include "caf/all.hpp" using std::cout; using std::cerr; using std::endl; using std::chrono::seconds; using namespace caf; namespace { // atoms for chopstick interface using put_atom = atom_constant; using take_atom = atom_constant; using busy_atom = atom_constant; using taken_atom = atom_constant; // atoms for philosopher interface using eat_atom = atom_constant; using think_atom = atom_constant; // a chopstick using chopstick = typed_actor ::with_either ::or_else, reacts_to>; chopstick::behavior_type taken_chopstick(chopstick::pointer self, actor_addr); // either taken by a philosopher or available chopstick::behavior_type available_chopstick(chopstick::pointer self) { return { [=](take_atom) { self->become(taken_chopstick(self, self->current_sender())); return taken_atom::value; }, [](put_atom) { cerr << "chopstick received unexpected 'put'" << endl; } }; } chopstick::behavior_type taken_chopstick(chopstick::pointer self, actor_addr user) { return { [](take_atom) { return busy_atom::value; }, [=](put_atom) { if (self->current_sender() == user) { self->become(available_chopstick(self)); } } }; } /* Based on: http://www.dalnefre.com/wp/2010/08/dining-philosophers-in-humus/ * * * +-------------+ {busy|taken} * /-------->| thinking |<------------------\ * | +-------------+ | * | | | * | | {eat} | * | | | * | V | * | +-------------+ {busy} +-------------+ * | | hungry |----------->| denied | * | +-------------+ +-------------+ * | | * | | {taken} * | | * | V * | +-------------+ * | | granted | * | +-------------+ * | | | * | {busy} | | {taken} * \-----------/ | * | V * | {think} +-------------+ * \---------| eating | * +-------------+ */ class philosopher : public event_based_actor { public: philosopher(const std::string& n, const chopstick& l, const chopstick& r) : name(n), left(l), right(r) { // a philosopher that receives {eat} stops thinking and becomes hungry thinking.assign( [=](eat_atom) { become(hungry); send(left, take_atom::value); send(right, take_atom::value); } ); // wait for the first answer of a chopstick hungry.assign( [=](taken_atom) { become(granted); }, [=](busy_atom) { become(denied); } ); // philosopher was able to obtain the first chopstick granted.assign( [=](taken_atom) { aout(this) << name << " has picked up chopsticks with IDs " << left->id() << " and " << right->id() << " and starts to eat\n"; // eat some time delayed_send(this, seconds(5), think_atom::value); become(eating); }, [=](busy_atom) { send(current_sender() == left ? right : left, put_atom::value); send(this, eat_atom::value); become(thinking); } ); // philosopher was *not* able to obtain the first chopstick denied.assign( [=](taken_atom) { send(current_sender() == left ? left : right, put_atom::value); send(this, eat_atom::value); become(thinking); }, [=](busy_atom) { send(this, eat_atom::value); become(thinking); } ); // philosopher obtained both chopstick and eats (for five seconds) eating.assign( [=](think_atom) { send(left, put_atom::value); send(right, put_atom::value); delayed_send(this, seconds(5), eat_atom::value); aout(this) << name << " puts down his chopsticks and starts to think\n"; become(thinking); } ); } protected: behavior make_behavior() override { // start thinking send(this, think_atom::value); // philosophers start to think after receiving {think} return ( [=](think_atom) { aout(this) << name << " starts to think\n"; delayed_send(this, seconds(5), eat_atom::value); become(thinking); } ); } private: std::string name; // the name of this philosopher chopstick left; // left chopstick chopstick right; // right chopstick behavior thinking; // initial behavior behavior hungry; // tries to take chopsticks behavior granted; // has one chopstick and waits for the second one behavior denied; // could not get first chopsticks behavior eating; // waits for some time, then go thinking again }; void dining_philosophers() { scoped_actor self; // create five chopsticks aout(self) << "chopstick ids are:"; std::vector chopsticks; for (size_t i = 0; i < 5; ++i) { chopsticks.push_back(spawn_typed(available_chopstick)); aout(self) << " " << chopsticks.back()->id(); } aout(self) << endl; // spawn five philosophers std::vector names {"Plato", "Hume", "Kant", "Nietzsche", "Descartes"}; for (size_t i = 0; i < 5; ++i) { spawn(names[i], chopsticks[i], chopsticks[(i + 1) % 5]); } } } // namespace int main(int, char**) { dining_philosophers(); // real philosophers are never done await_all_actors_done(); shutdown(); } actor-framework-0.13.2/examples/message_passing/typed_calculator.cpp000066400000000000000000000053041251275671500257450ustar00rootroot00000000000000/******************************************************************************\ * This example is a very basic, non-interactive math service implemented * * using typed actors. * \ ******************************************************************************/ #include #include #include "caf/all.hpp" using std::endl; using namespace caf; namespace { struct shutdown_request { }; struct plus_request { int a; int b; }; struct minus_request { int a; int b; }; using calculator_type = typed_actor::with, replies_to::with, replies_to::with>; calculator_type::behavior_type typed_calculator(calculator_type::pointer self) { return { [](const plus_request& pr) { return pr.a + pr.b; }, [](const minus_request& pr) { return pr.a - pr.b; }, [=](const shutdown_request&) { self->quit(); } }; } class typed_calculator_class : public calculator_type::base { protected: behavior_type make_behavior() override { return { [](const plus_request& pr) { return pr.a + pr.b; }, [](const minus_request& pr) { return pr.a - pr.b; }, [=](const shutdown_request&) { quit(); } }; } }; void tester(event_based_actor* self, const calculator_type& testee) { self->link_to(testee); // will be invoked if we receive an unexpected response message self->on_sync_failure([=] { aout(self) << "AUT (actor under test) failed" << endl; self->quit(exit_reason::user_shutdown); }); // first test: 2 + 1 = 3 self->sync_send(testee, plus_request{2, 1}).then( [=](int r1) { // second test: 2 - 1 = 1 self->sync_send(testee, minus_request{2, 1}).then( [=](int r2) { // both tests succeeded if (r1 == 3 && r2 == 1) { aout(self) << "AUT (actor under test) seems to be ok" << endl; } self->send(testee, shutdown_request{}); } ); } ); } } // namespace int main() { // announce custom message types announce("shutdown_request"); announce("plus_request", &plus_request::a, &plus_request::b); announce("minus_request", &minus_request::a, &minus_request::b); // test function-based impl spawn(tester, spawn_typed(typed_calculator)); await_all_actors_done(); // test class-based impl spawn(tester, spawn_typed()); await_all_actors_done(); // done shutdown(); return 0; } actor-framework-0.13.2/examples/qtsupport/000077500000000000000000000000001251275671500206125ustar00rootroot00000000000000actor-framework-0.13.2/examples/qtsupport/chatwidget.cpp000066400000000000000000000107551251275671500234510ustar00rootroot00000000000000#include #include #include "caf/all.hpp" #include "caf/detail/scope_guard.hpp" CAF_PUSH_WARNINGS #include #include CAF_POP_WARNINGS #include "chatwidget.hpp" using namespace std; using namespace caf; ChatWidget::ChatWidget(QWidget* parent, Qt::WindowFlags f) : super(parent, f), m_input(nullptr), m_output(nullptr) { set_message_handler ([=](local_actor* self) -> message_handler { return { on(atom("join"), arg_match) >> [=](const group& what) { if (m_chatroom) { self->send(m_chatroom, m_name + " has left the chatroom"); self->leave(m_chatroom); } self->join(what); print(("*** joined " + to_string(what)).c_str()); m_chatroom = what; self->send(what, m_name + " has entered the chatroom"); }, on(atom("setName"), arg_match) >> [=](string& name) { self->send(m_chatroom, m_name + " is now known as " + name); m_name = std::move(name); print("*** changed name to " + QString::fromUtf8(m_name.c_str())); }, on(atom("quit")) >> [=] { close(); // close widget }, [=](const string& txt) { // don't print own messages if (self != self->current_sender()) { print(QString::fromUtf8(txt.c_str())); } }, [=](const group_down_msg& gdm) { print("*** chatroom offline: " + QString::fromUtf8(to_string(gdm.source).c_str())); } }; }); } void ChatWidget::sendChatMessage() { auto cleanup = detail::make_scope_guard([=] { input()->setText(QString()); }); QString line = input()->text(); if (line.startsWith('/')) { vector words; split(words, line.midRef(1).toUtf8().constData(), is_any_of(" ")); message_builder(words.begin(), words.end()).apply({ on("join", arg_match) >> [=](const string& mod, const string& g) { group gptr; try { gptr = group::get(mod, g); } catch (exception& e) { print("*** exception: " + QString::fromUtf8((e.what()))); } if (gptr) { send_as(as_actor(), as_actor(), atom("join"), gptr); } }, on("setName", arg_match) >> [=](const string& str) { send_as(as_actor(), as_actor(), atom("setName"), str); }, others() >> [=] { print("*** list of commands:\n" "/join \n" "/setName \n"); } }); return; } if (m_name.empty()) { print("*** please set a name before sending messages"); return; } if (!m_chatroom) { print("*** no one is listening... please join a group"); return; } string msg = m_name; msg += ": "; msg += line.toUtf8().constData(); print(": " + input()->text()); send_as(as_actor(), m_chatroom, std::move(msg)); } void ChatWidget::joinGroup() { if (m_name.empty()) { QMessageBox::information(this, "No Name, No Chat", "Please set a name first."); return; } auto gname = QInputDialog::getText(this, "Join Group", "Please enter a group as :", QLineEdit::Normal, "remote:chatroom@localhost:4242"); int pos = gname.indexOf(':'); if (pos < 0) { QMessageBox::warning(this, "Not a Group", "Invalid format"); return; } string mod = gname.left(pos).toUtf8().constData(); string gid = gname.midRef(pos+1).toUtf8().constData(); try { auto gptr = group::get(mod, gid); send_as(as_actor(), as_actor(), atom("join"), gptr); } catch (exception& e) { QMessageBox::critical(this, "Exception", e.what()); } } void ChatWidget::changeName() { auto name = QInputDialog::getText(this, "Change Name", "Please enter a new name"); if (!name.isEmpty()) { send_as(as_actor(), as_actor(), atom("setName"), name.toUtf8().constData()); } } actor-framework-0.13.2/examples/qtsupport/chatwidget.hpp000066400000000000000000000022361251275671500234510ustar00rootroot00000000000000#include #include "caf/all.hpp" #include "caf/mixin/actor_widget.hpp" CAF_PUSH_WARNINGS #include #include #include CAF_POP_WARNINGS class ChatWidget : public caf::mixin::actor_widget { Q_OBJECT typedef caf::mixin::actor_widget super; public: ChatWidget(QWidget* parent = nullptr, Qt::WindowFlags f = 0); public slots: void sendChatMessage(); void joinGroup(); void changeName(); private: template T* get(T*& member, const char* name) { if (member == nullptr) { member = findChild(name); if (member == nullptr) throw std::runtime_error("unable to find child: " + std::string(name)); } return member; } inline QLineEdit* input() { return get(m_input, "input"); } inline QTextEdit* output() { return get(m_output, "output"); } inline void print(const QString& what) { output()->append(what); } QLineEdit* m_input; QTextEdit* m_output; std::string m_name; caf::group m_chatroom; }; actor-framework-0.13.2/examples/qtsupport/chatwindow.ui000066400000000000000000000075601251275671500233300ustar00rootroot00000000000000 ChatWindow 0 0 800 600 MainWindow 0 0 Qt::ClickFocus false true Qt::StrongFocus 0 0 QFrame::NoFrame QFrame::Raised 0 0 0 0 0 800 22 File Join Group Set Name ChatWidget QWidget
chatwidget.hpp
1 sendChatMessage() changeName() joinGroup()
actionJoin_Group activated() chatwidget joinGroup() -1 -1 399 300 actionSet_Name activated() chatwidget changeName() -1 -1 399 300 input returnPressed() chatwidget sendChatMessage() 362 547 399 310
actor-framework-0.13.2/examples/qtsupport/qt_group_chat.cpp000066400000000000000000000047601251275671500241640ustar00rootroot00000000000000/******************************************************************************\ * This example program represents a minimal GUI chat program * * based on group communication. This chat program is compatible to the * * terminal version in remote_actors/group_chat.cpp. * * * * Setup for a minimal chat between "alice" and "bob": * * - ./build/bin/group_server -p 4242 * * - ./build/bin/qt_group_chat -g remote:chatroom@localhost:4242 -n alice * * - ./build/bin/qt_group_chat -g remote:chatroom@localhost:4242 -n bob * \******************************************************************************/ #include #include #include #include #include #include #include #include "caf/all.hpp" CAF_PUSH_WARNINGS #include #include #include "ui_chatwindow.h" // auto generated from chatwindow.ui CAF_POP_WARNINGS using namespace std; using namespace caf; int main(int argc, char** argv) { string name; string group_id; auto res = message_builder(argv + 1, argv + argc).extract_opts({ {"name,n", "set chat name", name}, {"group,g", "join chat group", group_id} }); if (!res.remainder.empty()) { std::cerr << res.helptext << std::endl; return 1; } if (res.opts.count("help") > 0) { return 0; } group gptr; // evaluate group parameter if (!group_id.empty()) { auto p = group_id.find(':'); if (p == std::string::npos) { cerr << "*** error parsing argument " << group_id << ", expected format: :"; } else { try { gptr = group::get(group_id.substr(0, p), group_id.substr(p + 1)); } catch (exception& e) { cerr << "*** exception: group::get(\"" << group_id.substr(0, p) << "\", \"" << group_id.substr(p + 1) << "\") failed; " << to_verbose_string(e) << endl; } } } QApplication app(argc, argv); app.setQuitOnLastWindowClosed(true); QMainWindow mw; Ui::ChatWindow helper; helper.setupUi(&mw); auto client = helper.chatwidget->as_actor(); if (!name.empty()) { send_as(client, client, atom("setName"), move(name)); } if (gptr) { send_as(client, client, atom("join"), gptr); } mw.show(); auto app_res = app.exec(); await_all_actors_done(); shutdown(); return app_res; } actor-framework-0.13.2/examples/remote_actors/000077500000000000000000000000001251275671500213775ustar00rootroot00000000000000actor-framework-0.13.2/examples/remote_actors/distributed_calculator.cpp000066400000000000000000000222451251275671500266430ustar00rootroot00000000000000/******************************************************************************\ * This program is a distributed version of the math_actor example. * * Client and server use a stateless request/response protocol and the client * * is failure resilient by using a FIFO request queue. * * The client auto-reconnects and also allows for server reconfiguration. * * * * Run server at port 4242: * * - ./build/bin/distributed_math_actor -s -p 4242 * * * * Run client at the same host: * * - ./build/bin/distributed_math_actor -c -p 4242 * \ ******************************************************************************/ #include #include #include #include #include #include #include #include "caf/all.hpp" #include "caf/io/all.hpp" using std::cout; using std::cerr; using std::endl; using std::string; using namespace caf; namespace { using plus_atom = atom_constant; using minus_atom = atom_constant; using result_atom = atom_constant; using rebind_atom = atom_constant; using connect_atom = atom_constant; using reconnect_atom = atom_constant; // our "service" behavior calculator() { return { [](plus_atom, int a, int b) -> message { return make_message(result_atom::value, a + b); }, [](minus_atom, int a, int b) -> message { return make_message(result_atom::value, a - b); } }; } class client_impl : public event_based_actor { public: client_impl(string hostaddr, uint16_t port) : m_host(std::move(hostaddr)), m_port(port) { // nop } behavior make_behavior() override { become(awaiting_task()); become(keep_behavior, reconnecting()); return {}; } private: void sync_send_task(atom_value op, int lhs, int rhs) { on_sync_failure([=] { aout(this) << "*** sync_failure!" << endl; }); sync_send(m_server, op, lhs, rhs).then( [=](result_atom, int result) { aout(this) << lhs << (op == plus_atom::value ? " + " : " - ") << rhs << " = " << result << endl; }, [=](const sync_exited_msg& msg) { aout(this) << "*** server down [" << msg.reason << "], " << "try to reconnect ..." << endl; // try sync_sending this again after successful reconnect become(keep_behavior, reconnecting([=] { sync_send_task(op, lhs, rhs); })); } ); } behavior awaiting_task() { return { [=](atom_value op, int lhs, int rhs) { if (op != plus_atom::value && op != minus_atom::value) { return; } sync_send_task(op, lhs, rhs); }, [=](rebind_atom, string& nhost, uint16_t nport) { aout(this) << "*** rebind to " << nhost << ":" << nport << endl; using std::swap; swap(m_host, nhost); swap(m_port, nport); become(keep_behavior, reconnecting()); } }; } behavior reconnecting(std::function continuation = nullptr) { using std::chrono::seconds; auto mm = io::get_middleman_actor(); send(mm, get_atom::value, m_host, m_port); return { [=](ok_atom, const actor_addr& new_server) { aout(this) << "*** connection succeeded, awaiting tasks" << endl; m_server = actor_cast(new_server); // return to previous behavior if (continuation) { continuation(); } unbecome(); }, [=](error_atom, const string& errstr) { aout(this) << "*** could not connect to " << m_host << " at port " << m_port << ": " << errstr << " [try again in 3s]" << endl; delayed_send(mm, seconds(3), get_atom::value, m_host, m_port); }, [=](rebind_atom, string& nhost, uint16_t nport) { aout(this) << "*** rebind to " << nhost << ":" << nport << endl; using std::swap; swap(m_host, nhost); swap(m_port, nport); // await pending ok/error message first, then send new request to MM become( keep_behavior, (on() || on()) >> [=] { unbecome(); send(mm, get_atom::value, m_host, m_port); } ); }, // simply ignore all requests until we have a connection others >> skip_message }; } actor m_server; string m_host; uint16_t m_port; }; // removes leading and trailing whitespaces string trim(std::string s) { auto not_space = [](char c) { return !isspace(c); }; // trim left s.erase(s.begin(), find_if(s.begin(), s.end(), not_space)); // trim right s.erase(find_if(s.rbegin(), s.rend(), not_space).base(), s.end()); return s; } // tries to convert `str` to an int optional toint(const string& str) { char* end; auto result = static_cast(strtol(str.c_str(), &end, 10)); if (end == str.c_str() + str.size()) { return result; } return none; } // converts "+" to the atom '+' and "-" to the atom '-' optional plus_or_minus(const string& str) { if (str == "+") { return {plus_atom::value}; } if (str == "-") { return {minus_atom::value}; } return none; } void client_repl(string host, uint16_t port) { // keeps track of requests and tries to reconnect on server failures auto usage = [] { cout << "Usage:" << endl << " quit : terminates the program" << endl << " connect : connects to a remote actor" << endl << " + : adds two integers" << endl << " - : subtracts two integers" << endl << endl; }; usage(); bool done = false; auto client = spawn(std::move(host), port); // defining the handler outside the loop is more efficient as it avoids // re-creating the same object over and over again message_handler eval{ on("quit") >> [&] { anon_send_exit(client, exit_reason::user_shutdown); done = true; }, on("connect", arg_match) >> [&](string& nhost, string& sport) { try { auto lport = std::stoul(sport); if (lport < std::numeric_limits::max()) { anon_send(client, rebind_atom::value, move(nhost), static_cast(lport)); } else { cout << lport << " is not a valid port" << endl; } } catch (std::exception&) { cout << "\"" << sport << "\" is not an unsigned integer" << endl; } }, on(toint, plus_or_minus, toint) >> [&](int x, atom_value op, int y) { anon_send(client, op, x, y); }, others >> usage }; // read next line, split it, and feed to the eval handler string line; while (!done && std::getline(std::cin, line)) { line = trim(std::move(line)); // ignore leading and trailing whitespaces std::vector words; split(words, line, is_any_of(" "), token_compress_on); message_builder(words.begin(), words.end()).apply(eval); } } } // namespace int main(int argc, char** argv) { uint16_t port = 0; string host = "localhost"; auto res = message_builder(argv + 1, argv + argc).extract_opts({ {"port,p", "set port (either to publish at or to connect to)", port}, {"host,H", "set host (client mode only, default: localhost)", host}, {"server,s", "run in server mode"}, {"client,c", "run in client mode"} }); if (res.opts.count("help") > 0) { // help text has already been printed return 0; } if (!res.remainder.empty()) { // not all CLI arguments could be consumed cerr << "*** invalid command line options" << endl << res.helptext << endl; return 1; } bool is_server = res.opts.count("server") > 0; if (is_server == (res.opts.count("client") > 0)) { if (is_server) { cerr << "*** cannot be server and client at the same time" << endl; } else { cerr << "*** either --server or --client option must be set" << endl; } return 1; } if (!is_server && port == 0) { cerr << "*** no port to server specified" << endl; return 1; } if (is_server) { auto calc = spawn(calculator); try { // try to publish math actor at given port cout << "*** try publish at port " << port << endl; auto p = io::publish(calc, port); cout << "*** server successfully published at port " << p << endl; cout << "*** press [enter] to quit" << endl; string dummy; std::getline(std::cin, dummy); cout << "... cya" << endl; } catch (std::exception& e) { cerr << "*** unable to publish math actor at port " << port << "\n" << to_verbose_string(e) // prints exception type and e.what() << endl; } anon_send_exit(calc, exit_reason::user_shutdown); } else { client_repl(host, port); } await_all_actors_done(); shutdown(); } actor-framework-0.13.2/examples/remote_actors/group_chat.cpp000066400000000000000000000120761251275671500242440ustar00rootroot00000000000000/******************************************************************************\ * This example program represents a minimal terminal chat program * * based on group communication. * * * * Setup for a minimal chat between "alice" and "bob": * * - ./build/bin/group_server -p 4242 * * - ./build/bin/group_chat -g remote:chatroom@localhost:4242 -n alice * * - ./build/bin/group_chat -g remote:chatroom@localhost:4242 -n bob * \ ******************************************************************************/ #include #include #include #include #include #include #include "caf/all.hpp" #include "caf/io/all.hpp" #include "caf/string_algorithms.hpp" using namespace std; using namespace caf; using broadcast_atom = atom_constant; struct line { string str; }; istream& operator>>(istream& is, line& l) { getline(is, l.str); return is; } namespace { string s_last_line; } void client(event_based_actor* self, const string& name) { self->become ( [=](broadcast_atom, const string& message) { for(auto& dest : self->joined_groups()) { self->send(dest, name + ": " + message); } }, [=](join_atom, const group& what) { for (auto g : self->joined_groups()) { cout << "*** leave " << to_string(g) << endl; self->send(self, g, name + " has left the chatroom"); self->leave(g); } cout << "*** join " << to_string(what) << endl; self->join(what); self->send(what, name + " has entered the chatroom"); }, [=](const string& txt) { // don't print own messages if (self->current_sender() != self) cout << txt << endl; }, [=](const group_down_msg& g) { cout << "*** chatroom offline: " << to_string(g.source) << endl; }, others >> [=]() { cout << "unexpected: " << to_string(self->current_message()) << endl; } ); } int main(int argc, char** argv) { string name; string group_id; auto res = message_builder(argv + 1, argv + argc).extract_opts({ {"name,n", "set name", name}, {"group,g", "join group", group_id} }); if (!res.remainder.empty()) { std::cout << res.helptext << std::endl; return 1; } if (res.opts.count("help") > 0) { return 0; } while (name.empty()) { cout << "please enter your name: " << flush; if (!getline(cin, name)) { cerr << "*** no name given... terminating" << endl; return 1; } } auto client_actor = spawn(client, name); // evaluate group parameters if (!group_id.empty()) { auto p = group_id.find(':'); if (p == std::string::npos) { cerr << "*** error parsing argument " << group_id << ", expected format: :"; } else { try { auto module = group_id.substr(0, p); auto group_uri = group_id.substr(p + 1); auto g = (module == "remote") ? io::remote_group(group_uri) : group::get(module, group_uri); anon_send(client_actor, join_atom::value, g); } catch (exception& e) { cerr << "*** exception: group::get(\"" << group_id.substr(0, p) << "\", \"" << group_id.substr(p + 1) << "\") failed; " << to_verbose_string(e) << endl; } } } cout << "*** starting client, type '/help' for a list of commands" << endl; auto starts_with = [](const string& str) -> function (const string&)> { return [=](const string& arg) -> optional { if (arg.compare(0, str.size(), str) == 0) { return arg; } return none; }; }; istream_iterator eof; vector words; for (istream_iterator i(cin); i != eof; ++i) { words.clear(); split(words, i->str, is_any_of(" ")); message_builder(words.begin(), words.end()).apply({ on("/join", arg_match) >> [&](const string& mod, const string& id) { try { group grp = (mod == "remote") ? io::remote_group(id) : group::get(mod, id); anon_send(client_actor, join_atom::value, grp); } catch (exception& e) { cerr << "*** exception: " << to_verbose_string(e) << endl; } }, on("/quit") >> [&] { // close STDIN; causes this match loop to quit cin.setstate(ios_base::eofbit); }, on(starts_with("/"), any_vals) >> [&] { cout << "*** available commands:\n" " /join join a new chat channel\n" " /quit quit the program\n" " /help print this text\n" << flush; }, others >> [&] { if (!s_last_line.empty()) { anon_send(client_actor, broadcast_atom::value, s_last_line); } } }); } // force actor to quit anon_send_exit(client_actor, exit_reason::user_shutdown); await_all_actors_done(); shutdown(); } actor-framework-0.13.2/examples/remote_actors/group_server.cpp000066400000000000000000000047401251275671500246320ustar00rootroot00000000000000/******************************************************************************\ * This example program represents a minimal IRC-like group * * communication server. * * * * Setup for a minimal chat between "alice" and "bob": * * - ./build/bin/group_server -p 4242 * * - ./build/bin/group_chat -g remote:chatroom@localhost:4242 -n alice * * - ./build/bin/group_chat -g remote:chatroom@localhost:4242 -n bob * \ ******************************************************************************/ #include #include #include #include "caf/all.hpp" #include "caf/io/all.hpp" using namespace std; using namespace caf; optional to_port(const string& arg) { char* last = nullptr; auto res = strtoul(arg.c_str(), &last, 10); if (last == (arg.c_str() + arg.size()) && res <= 65536) { return static_cast(res); } return none; } optional long_port(const string& arg) { if (arg.compare(0, 7, "--port=") == 0) { return to_port(arg.substr(7)); } return none; } int main(int argc, char** argv) { uint16_t port = 0; message_builder{argv + 1, argv + argc}.apply({ (on("-p", to_port) || on(long_port)) >> [&](uint16_t arg) { port = arg; } }); if (port <= 1024) { cerr << "*** no port > 1024 given" << endl; cout << "options:" << endl << " -p | --port= set port" << endl; return 1; } try { // try to bind the group server to the given port, // this allows other nodes to access groups of this server via // group::get("remote", "@:"); // note: it is not needed to explicitly create a on the server, // as groups are created on-the-fly on first usage io::publish_local_groups(port); } catch (bind_failure& e) { // thrown if is already in use cerr << "*** bind_failure: " << e.what() << endl; return 2; } catch (network_error& e) { // thrown on errors in the socket API cerr << "*** network error: " << e.what() << endl; return 2; } cout << "type 'quit' to shutdown the server" << endl; string line; while (getline(cin, line)) { if (line == "quit") { return 0; } else { cerr << "illegal command" << endl; } } shutdown(); } actor-framework-0.13.2/examples/remote_actors/pingpong.proto000066400000000000000000000002661251275671500243110ustar00rootroot00000000000000package org.libcppa; message Ping { required int32 id = 1; } message Pong { required int32 id = 1; } message PingOrPong { optional Ping ping = 1; optional Pong pong = 2; } actor-framework-0.13.2/examples/type_system/000077500000000000000000000000001251275671500211165ustar00rootroot00000000000000actor-framework-0.13.2/examples/type_system/announce_1.cpp000066400000000000000000000055261251275671500236600ustar00rootroot00000000000000#include #include #include #include #include "caf/all.hpp" #include "caf/binary_serializer.hpp" #include "caf/binary_deserializer.hpp" using std::cout; using std::endl; using std::vector; using namespace caf; // POD struct struct foo { std::vector a; int b; }; // announce requires foo to have the equal operator implemented bool operator==(const foo& lhs, const foo& rhs) { return lhs.a == rhs.a && lhs.b == rhs.b; } // a pair of two ints using foo_pair = std::pair; // another pair of two ints using foo_pair2 = std::pair; // a struct with member vector> struct foo2 { int a; vector> b; }; bool operator==( const foo2& lhs, const foo2& rhs ) { return lhs.a == rhs.a && lhs.b == rhs.b; } // receives `remaining` messages void testee(event_based_actor* self, size_t remaining) { auto set_next_behavior = [=] { if (remaining > 1) testee(self, remaining - 1); else self->quit(); }; self->become ( // note: we sent a foo_pair2, but match on foo_pair // that's safe because both are aliases for std::pair on() >> [=](const foo_pair& val) { cout << "foo_pair(" << val.first << ", " << val.second << ")" << endl; set_next_behavior(); }, on() >> [=](const foo& val) { cout << "foo({"; auto i = val.a.begin(); auto end = val.a.end(); if (i != end) { cout << *i; while (++i != end) { cout << ", " << *i; } } cout << "}, " << val.b << ")" << endl; set_next_behavior(); } ); } int main(int, char**) { // announces foo to the libcaf type system; // the function expects member pointers to all elements of foo announce("foo", &foo::a, &foo::b); // announce foo2 to the libcaf type system, // note that recursive containers are managed automatically by libcaf announce("foo2", &foo2::a, &foo2::b); foo2 vd; vd.a = 5; vd.b.resize(1); vd.b.back().push_back(42); vector buf; binary_serializer bs(std::back_inserter(buf)); bs << vd; binary_deserializer bd(buf.data(), buf.size()); foo2 vd2; uniform_typeid()->deserialize(&vd2, &bd); assert(vd == vd2); // announce std::pair to the type system announce("foo_pair", &foo_pair::first, &foo_pair::second); // libcaf returns the same uniform_type_info // instance for the type aliases foo_pair and foo_pair2 assert(uniform_typeid() == uniform_typeid()); // spawn a testee that receives two messages auto t = spawn(testee, 2); { scoped_actor self; // send t a foo self->send(t, foo{std::vector{1, 2, 3, 4}, 5}); // send t a foo_pair2 self->send(t, foo_pair2{3, 4}); } await_all_actors_done(); shutdown(); return 0; } actor-framework-0.13.2/examples/type_system/announce_2.cpp000066400000000000000000000024461251275671500236570ustar00rootroot00000000000000#include #include #include "caf/all.hpp" using std::cout; using std::endl; using std::make_pair; using namespace caf; // a simple class using getter and setter member functions class foo { int m_a; int m_b; public: foo(int a0 = 0, int b0 = 0) : m_a(a0), m_b(b0) { } foo(const foo&) = default; foo& operator=(const foo&) = default; int a() const { return m_a; } void set_a(int val) { m_a = val; } int b() const { return m_b; } void set_b(int val) { m_b = val; } }; // announce requires foo to be comparable bool operator==(const foo& lhs, const foo& rhs) { return lhs.a() == rhs.a() && lhs.b() == rhs.b(); } void testee(event_based_actor* self) { self->become ( on() >> [=](const foo& val) { aout(self) << "foo(" << val.a() << ", " << val.b() << ")" << endl; self->quit(); } ); } int main(int, char**) { // if a class uses getter and setter member functions, // we pass those to the announce function as { getter, setter } pairs. announce("foo", make_pair(&foo::a, &foo::set_a), make_pair(&foo::b, &foo::set_b)); { scoped_actor self; auto t = spawn(testee); self->send(t, foo{1, 2}); } await_all_actors_done(); shutdown(); return 0; } actor-framework-0.13.2/examples/type_system/announce_3.cpp000066400000000000000000000040211251275671500236470ustar00rootroot00000000000000#include #include #include "caf/all.hpp" using std::cout; using std::endl; using std::make_pair; using namespace caf; // a simple class using overloaded getter and setter member functions class foo { int m_a; int m_b; public: foo() : m_a(0), m_b(0) { } foo(int a0, int b0) : m_a(a0), m_b(b0) { } foo(const foo&) = default; foo& operator=(const foo&) = default; int a() const { return m_a; } void a(int val) { m_a = val; } int b() const { return m_b; } void b(int val) { m_b = val; } }; // announce requires foo to have the equal operator implemented bool operator==(const foo& lhs, const foo& rhs) { return lhs.a() == rhs.a() && lhs.b() == rhs.b(); } // a member function pointer to get an attribute of foo using foo_getter = int (foo::*)() const; // a member function pointer to set an attribute of foo using foo_setter = void (foo::*)(int); void testee(event_based_actor* self) { self->become ( on() >> [=](const foo& val) { aout(self) << "foo(" << val.a() << ", " << val.b() << ")" << endl; self->quit(); } ); } int main(int, char**) { // since the member function "a" is ambiguous, the compiler // also needs a type to select the correct overload foo_getter g1 = &foo::a; foo_setter s1 = &foo::a; // same is true for b foo_getter g2 = &foo::b; foo_setter s2 = &foo::b; // equal to example 3 announce("foo", make_pair(g1, s1), make_pair(g2, s2)); // alternative syntax that uses casts instead of variables // (returns false since foo is already announced) announce("foo", make_pair(static_cast(&foo::a), static_cast(&foo::a)), make_pair(static_cast(&foo::b), static_cast(&foo::b))); // spawn a new testee and send it a foo { scoped_actor self; self->send(spawn(testee), foo{1, 2}); } await_all_actors_done(); shutdown(); return 0; } actor-framework-0.13.2/examples/type_system/announce_4.cpp000066400000000000000000000065051251275671500236610ustar00rootroot00000000000000#include #include "caf/all.hpp" #include "caf/to_string.hpp" using std::cout; using std::endl; using std::make_pair; using namespace caf; // the foo class from example 3 class foo { int m_a; int m_b; public: foo() : m_a(0), m_b(0) { } foo(int a0, int b0) : m_a(a0), m_b(b0) { } foo(const foo&) = default; foo& operator=(const foo&) = default; int a() const { return m_a; } void set_a(int val) { m_a = val; } int b() const { return m_b; } void set_b(int val) { m_b = val; } }; // needed for operator==() of bar bool operator==(const foo& lhs, const foo& rhs) { return lhs.a() == rhs.a() && lhs.b() == rhs.b(); } // simple struct that has foo as a member struct bar { foo f; int i; }; // announce requires bar to have the equal operator implemented bool operator==(const bar& lhs, const bar& rhs) { return lhs.f == rhs.f && lhs.i == rhs.i; } // "worst case" class ... not a good software design at all ;) class baz { foo m_f; public: bar b; // announce requires a default constructor baz() = default; inline baz(const foo& mf, const bar& mb) : m_f(mf), b(mb) { } const foo& f() const { return m_f; } void set_f(const foo& val) { m_f = val; } }; // even worst case classes have to implement operator== bool operator==(const baz& lhs, const baz& rhs) { return lhs.f() == rhs.f() && lhs.b == rhs.b; } // receives `remaining` messages void testee(event_based_actor* self, size_t remaining) { auto set_next_behavior = [=] { if (remaining > 1) testee(self, remaining - 1); else self->quit(); }; self->become ( on() >> [=](const bar& val) { aout(self) << "bar(foo(" << val.f.a() << ", " << val.f.b() << "), " << val.i << ")" << endl; set_next_behavior(); }, on() >> [=](const baz& val) { // prints: baz ( foo ( 1, 2 ), bar ( foo ( 3, 4 ), 5 ) ) aout(self) << to_string(make_message(val)) << endl; set_next_behavior(); } ); } int main(int, char**) { // bar has a non-trivial data member f, thus, we have to told // announce how to serialize/deserialize this member; // this is was the compound_member function is for; // it takes a pointer to the non-trivial member as first argument // followed by all "sub-members" either as member pointer or // { getter, setter } pair auto meta_bar_f = [] { return compound_member(&bar::f, make_pair(&foo::a, &foo::set_a), make_pair(&foo::b, &foo::set_b)); }; // with meta_bar_f, we can now announce bar announce("bar", meta_bar_f(), &bar::i); // baz has non-trivial data members with getter/setter pair // and getter returning a mutable reference announce("baz", compound_member(make_pair(&baz::f, &baz::set_f), make_pair(&foo::a, &foo::set_a), make_pair(&foo::b, &foo::set_b)), // compound member that has a compound member compound_member(&baz::b, meta_bar_f(), &bar::i)); // spawn a testee that receives two messages auto t = spawn(testee, 2); { scoped_actor self; self->send(t, bar{foo{1, 2}, 3}); self->send(t, baz{foo{1, 2}, bar{foo{3, 4}, 5}}); } await_all_actors_done(); shutdown(); return 0; } actor-framework-0.13.2/examples/type_system/announce_5.cpp000066400000000000000000000142741251275671500236640ustar00rootroot00000000000000/****************************************************************************** * This example shows how to implement serialize/deserialize to announce * * non-trivial data structures to the libcaf type system. * * * * Announce() auto-detects STL compliant containers and provides * * an easy way to tell libcaf how to serialize user defined types. * * See announce_example 1-4 for usage examples. * * * * You should use "hand written" serialize/deserialize implementations * * if and only if there is no other way. * ******************************************************************************/ #include #include #include "caf/all.hpp" #include "caf/to_string.hpp" using std::cout; using std::endl; using namespace caf; namespace { // a node containing an integer and a vector of children struct tree_node { std::uint32_t value; std::vector children; tree_node(std::uint32_t v = 0) : value(v) { } tree_node& add_child(std::uint32_t v = 0) { children.push_back({ v }); return *this; } tree_node(const tree_node&) = default; // recursively print this node and all of its children to stdout void print() const { // format is: value { children0, children1, ..., childrenN } // e.g., 10 { 20 { 21, 22 }, 30 } cout << value; if (children.empty() == false) { cout << " { "; auto begin = children.begin(); auto end = children.end(); for (auto i = begin; i != end; ++i) { if (i != begin) { cout << ", "; } i->print(); } cout << " } "; } } }; // a very primitive tree implementation struct tree { tree_node root; // print tree to stdout void print() const { cout << "tree::print: "; root.print(); cout << endl; } }; // tree nodes are equals if values and all values of all children are equal bool operator==(const tree_node& lhs, const tree_node& rhs) { return (lhs.value == rhs.value) && (lhs.children == rhs.children); } bool operator==(const tree& lhs, const tree& rhs) { return lhs.root == rhs.root; } // abstract_uniform_type_info implements all functions of uniform_type_info // except for serialize() and deserialize() if the template parameter T: // - does have a default constructor // - does have a copy constructor // - does provide operator== class tree_type_info : public detail::abstract_uniform_type_info { public: tree_type_info() : detail::abstract_uniform_type_info("tree") { // nop } protected: void serialize(const void* ptr, serializer* sink) const { // ptr is guaranteed to be a pointer of type tree auto tree_ptr = reinterpret_cast(ptr); // recursively serialize nodes, beginning with root serialize_node(tree_ptr->root, sink); } void deserialize(void* ptr, deserializer* source) const { // ptr is guaranteed to be a pointer of type tree auto tree_ptr = reinterpret_cast(ptr); tree_ptr->root.children.clear(); // recursively deserialize nodes, beginning with root deserialize_node(tree_ptr->root, source); } private: void serialize_node(const tree_node& node, serializer* sink) const { // value, ... children ... sink->write_value(node.value); sink->begin_sequence(node.children.size()); for (const tree_node& subnode : node.children) { serialize_node(subnode, sink); } sink->end_sequence(); } void deserialize_node(tree_node& node, deserializer* source) const { // value, ... children ... auto value = source->read(); node.value = value; auto num_children = source->begin_sequence(); for (size_t i = 0; i < num_children; ++i) { node.add_child(); deserialize_node(node.children.back(), source); } source->end_sequence(); } }; using tree_vector = std::vector; // receives `remaining` messages void testee(event_based_actor* self, size_t remaining) { auto set_next_behavior = [=] { if (remaining > 1) testee(self, remaining - 1); else self->quit(); }; self->become ( [=](const tree& tmsg) { // prints the tree in its serialized format: // @<> ( { tree ( 0, { 10, { 11, { }, 12, { }, 13, { } }, 20, { 21, { }, 22, { } } } ) } ) cout << "to_string(self->current_message()): " << to_string(self->current_message()) << endl; // prints the tree using the print member function: // 0 { 10 { 11, 12, 13 } , 20 { 21, 22 } } tmsg.print(); set_next_behavior(); }, [=](const tree_vector& trees) { // prints "received 2 trees" cout << "received " << trees.size() << " trees" << endl; // prints: // @<> ( { // std::vector> ( { // tree ( 0, { 10, { 11, { }, 12, { }, 13, { } }, 20, { 21, { }, 22, { } } } ), // tree ( 0, { 10, { 11, { }, 12, { }, 13, { } }, 20, { 21, { }, 22, { } } } ) // ) // } ) cout << "to_string: " << to_string(self->current_message()) << endl; set_next_behavior(); } ); } } // namespace int main() { // the tree_type_info is owned by libcaf after this function call announce(typeid(tree), std::unique_ptr{new tree_type_info}); announce("tree_vector"); tree t0; // create a tree and fill it with some data t0.root.add_child(10); t0.root.children.back().add_child(11).add_child(12).add_child(13); t0.root.add_child(20); t0.root.children.back().add_child(21).add_child(22); /* tree t is now: 0 / \ / \ / \ 10 20 / |\ / \ / | \ / \ 11 12 13 21 22 */ { // lifetime scope of self scoped_actor self; // spawn a testee that receives two messages auto t = spawn(testee, 2); // send a tree self->send(t, t0); // send a vector of trees tree_vector tvec; tvec.push_back(t0); tvec.push_back(t0); self->send(t, tvec); } await_all_actors_done(); shutdown(); return 0; } actor-framework-0.13.2/libcaf_core/000077500000000000000000000000001251275671500171435ustar00rootroot00000000000000actor-framework-0.13.2/libcaf_core/CMakeLists.txt000066400000000000000000000066261251275671500217150ustar00rootroot00000000000000cmake_minimum_required(VERSION 2.8) project(caf_core C CXX) set (CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}) include_directories(.) # get header files; only needed by CMake generators, # e.g., for creating proper Xcode projects file(GLOB LIBCAF_CORE_HDRS "caf/*.hpp" "caf/detail/*.hpp" "caf/policy/*.hpp" "caf/mixin/*.hpp" "caf/scheduler/*.hpp" "cppa/*.hpp") # list cpp files excluding platform-dependent files set (LIBCAF_CORE_SRCS src/abstract_actor.cpp src/abstract_channel.cpp src/abstract_group.cpp src/abstract_coordinator.cpp src/actor.cpp src/actor_addr.cpp src/actor_companion.cpp src/actor_namespace.cpp src/actor_ostream.cpp src/actor_pool.cpp src/actor_proxy.cpp src/actor_registry.cpp src/attachable.cpp src/behavior.cpp src/behavior_stack.cpp src/behavior_impl.cpp src/binary_deserializer.cpp src/binary_serializer.cpp src/blocking_actor.cpp src/channel.cpp src/concatenated_tuple.cpp src/continue_helper.cpp src/decorated_tuple.cpp src/default_attachable.cpp src/deserializer.cpp src/duration.cpp src/either.cpp src/event_based_actor.cpp src/exception.cpp src/execution_unit.cpp src/exit_reason.cpp src/forwarding_actor_proxy.cpp src/get_mac_addresses.cpp src/get_root_uuid.cpp src/group.cpp src/group_manager.cpp src/match_case.cpp src/local_actor.cpp src/logging.cpp src/mailbox_element.cpp src/memory.cpp src/memory_managed.cpp src/message.cpp src/message_builder.cpp src/message_data.cpp src/message_handler.cpp src/node_id.cpp src/ref_counted.cpp src/response_promise.cpp src/replies_to.cpp src/resumable.cpp src/ripemd_160.cpp src/scoped_actor.cpp src/set_scheduler.cpp src/serializer.cpp src/shared_spinlock.cpp src/shutdown.cpp src/singletons.cpp src/string_algorithms.cpp src/string_serialization.cpp src/sync_request_bouncer.cpp src/try_match.cpp src/uniform_type_info.cpp src/uniform_type_info_map.cpp) add_custom_target(libcaf_core) # build shared library if not compiling static only if (NOT CAF_BUILD_STATIC_ONLY) add_library(libcaf_core_shared SHARED ${LIBCAF_CORE_SRCS} ${LIBCAF_CORE_HDRS}) target_link_libraries(libcaf_core_shared ${LD_FLAGS}) set_target_properties(libcaf_core_shared PROPERTIES SOVERSION ${CAF_VERSION} VERSION ${CAF_VERSION} OUTPUT_NAME caf_core) if(NOT WIN32) install(TARGETS libcaf_core_shared LIBRARY DESTINATION lib) endif() add_dependencies(libcaf_core_shared libcaf_core) endif () # build static library only if --build-static or --build-static-only was set if (CAF_BUILD_STATIC_ONLY OR CAF_BUILD_STATIC) add_library(libcaf_core_static STATIC ${LIBCAF_CORE_HDRS} ${LIBCAF_CORE_SRCS}) target_link_libraries(libcaf_core_static ${LD_FLAGS}) set_target_properties(libcaf_core_static PROPERTIES OUTPUT_NAME caf_core_static) if(NOT WIN32) install(TARGETS libcaf_core_static ARCHIVE DESTINATION lib) endif() add_dependencies(libcaf_core_static libcaf_core) endif () link_directories(${LD_DIRS}) include_directories(. ${INCLUDE_DIRS}) actor-framework-0.13.2/libcaf_core/caf/000077500000000000000000000000001251275671500176745ustar00rootroot00000000000000actor-framework-0.13.2/libcaf_core/caf/abstract_actor.hpp000066400000000000000000000215311251275671500234020ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_ABSTRACT_ACTOR_HPP #define CAF_ABSTRACT_ACTOR_HPP #include #include #include #include #include #include #include #include #include #include #include "caf/fwd.hpp" #include "caf/node_id.hpp" #include "caf/attachable.hpp" #include "caf/message_id.hpp" #include "caf/exit_reason.hpp" #include "caf/intrusive_ptr.hpp" #include "caf/abstract_channel.hpp" #include "caf/detail/type_traits.hpp" #include "caf/detail/functor_attachable.hpp" namespace caf { /** * A unique actor ID. * @relates abstract_actor */ using actor_id = uint32_t; /** * Denotes an ID that is never used by an actor. */ constexpr actor_id invalid_actor_id = 0; using abstract_actor_ptr = intrusive_ptr; /** * Base class for all actor implementations. */ class abstract_actor : public abstract_channel { public: /** * Attaches `ptr` to this actor. The actor will call `ptr->detach(...)` on * exit, or immediately if it already finished execution. */ void attach(attachable_ptr ptr); /** * Convenience function that attaches the functor `f` to this actor. The * actor executes `f()` on exit or immediatley if it is not running. */ template void attach_functor(F f) { attach(attachable_ptr{new detail::functor_attachable(std::move(f))}); } /** * Returns the logical actor address. */ actor_addr address() const; /** * Detaches the first attached object that matches `what`. */ size_t detach(const attachable::token& what); /** * Links this actor to `whom`. */ inline void link_to(const actor_addr& whom) { link_impl(establish_link_op, whom); } /** * Links this actor to `whom`. */ template void link_to(const ActorHandle& whom) { link_to(whom.address()); } /** * Unlinks this actor from `whom`. */ inline void unlink_from(const actor_addr& other) { link_impl(remove_link_op, other); } /** * Unlinks this actor from `whom`. */ template void unlink_from(const ActorHandle& other) { unlink_from(other.address()); } /** * Establishes a link relation between this actor and `other` * and returns whether the operation succeeded. */ inline bool establish_backlink(const actor_addr& other) { return link_impl(establish_backlink_op, other); } /** * Removes the link relation between this actor and `other` * and returns whether the operation succeeded. */ inline bool remove_backlink(const actor_addr& other) { return link_impl(remove_backlink_op, other); } /** * Returns the unique ID of this actor. */ inline uint32_t id() const { return m_id; } /** * Returns the actor's exit reason or * `exit_reason::not_exited` if it's still alive. */ inline uint32_t exit_reason() const { return m_exit_reason; } /** * Returns the set of accepted messages types as strings or * an empty set if this actor is untyped. */ virtual std::set message_types() const; /** * Returns the execution unit currently used by this actor. * @warning not thread safe */ inline execution_unit* host() const { return m_host; } /** * Sets the execution unit for this actor. */ inline void host(execution_unit* new_host) { m_host = new_host; } protected: /** * Creates a non-proxy instance. */ abstract_actor(); /** * Creates a proxy instance for a proxy running on `nid`. */ abstract_actor(actor_id aid, node_id nid); /** * Called by the runtime system to perform cleanup actions for this actor. * Subtypes should always call this member function when overriding it. */ void cleanup(uint32_t reason); /** * Returns `exit_reason() != exit_reason::not_exited`. */ inline bool exited() const { return exit_reason() != exit_reason::not_exited; } /**************************************************************************** * here be dragons: end of public interface * ****************************************************************************/ public: /** @cond PRIVATE */ enum linking_operation { establish_link_op, establish_backlink_op, remove_link_op, remove_backlink_op }; // used by ... static constexpr int trap_exit_flag = 0x01; // local_actor static constexpr int has_timeout_flag = 0x02; // single_timeout static constexpr int is_registered_flag = 0x04; // (several actors) static constexpr int is_initialized_flag = 0x08; // event-based actors static constexpr int is_blocking_flag = 0x10; // blocking_actor static constexpr int is_detached_flag = 0x20; // local_actor static constexpr int is_priority_aware_flag = 0x40; // local_actor inline void set_flag(bool enable_flag, int mask) { auto x = flags(); flags(enable_flag ? x | mask : x & ~mask); } inline bool get_flag(int mask) const { return static_cast(flags() & mask); } inline bool has_timeout() const { return get_flag(has_timeout_flag); } inline void has_timeout(bool value) { set_flag(value, has_timeout_flag); } inline bool is_registered() const { return get_flag(is_registered_flag); } void is_registered(bool value); inline bool is_initialized() const { return get_flag(is_initialized_flag); } inline void is_initialized(bool value) { set_flag(value, is_initialized_flag); } inline bool is_blocking() const { return get_flag(is_blocking_flag); } inline void is_blocking(bool value) { set_flag(value, is_blocking_flag); } inline bool is_detached() const { return get_flag(is_detached_flag); } inline void is_detached(bool value) { set_flag(value, is_detached_flag); } inline bool is_priority_aware() const { return get_flag(is_priority_aware_flag); } inline void is_priority_aware(bool value) { set_flag(value, is_priority_aware_flag); } // Tries to run a custom exception handler for `eptr`. optional handle(const std::exception_ptr& eptr); protected: virtual bool link_impl(linking_operation op, const actor_addr& other); bool establish_link_impl(const actor_addr& other); bool remove_link_impl(const actor_addr& other); bool establish_backlink_impl(const actor_addr& other); bool remove_backlink_impl(const actor_addr& other); inline void attach_impl(attachable_ptr& ptr) { ptr->next.swap(m_attachables_head); m_attachables_head.swap(ptr); } static size_t detach_impl(const attachable::token& what, attachable_ptr& ptr, bool stop_on_first_hit = false, bool dry_run = false); // cannot be changed after construction const actor_id m_id; // initially set to exit_reason::not_exited std::atomic m_exit_reason; // guards access to m_exit_reason, m_attachables, m_links, // and enqueue operations if actor is thread-mapped mutable std::mutex m_mtx; // only used in blocking and thread-mapped actors mutable std::condition_variable m_cv; // attached functors that are executed on cleanup (monitors, links, etc) attachable_ptr m_attachables_head; // identifies the execution unit this actor is currently executed by execution_unit* m_host; /** @endcond */ }; } // namespace caf #endif // CAF_ABSTRACT_ACTOR_HPP actor-framework-0.13.2/libcaf_core/caf/abstract_channel.hpp000066400000000000000000000103661251275671500237060ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_ABSTRACT_CHANNEL_HPP #define CAF_ABSTRACT_CHANNEL_HPP #include #include "caf/fwd.hpp" #include "caf/node_id.hpp" #include "caf/message_id.hpp" #include "caf/ref_counted.hpp" namespace caf { /** * Interface for all message receivers. * This interface describes an * entity that can receive messages and is implemented by {@link actor} * and {@link group}. */ class abstract_channel : public ref_counted { public: friend class abstract_actor; friend class abstract_group; virtual ~abstract_channel(); /** * Enqueues a new message to the channel. */ virtual void enqueue(const actor_addr& sender, message_id mid, message content, execution_unit* host) = 0; /** * Enqueues a new message wrapped in a `mailbox_element` to the channel. * This variant is used by actors whenever it is possible to allocate * mailbox element and message on the same memory block and is thus * more efficient. Non-actors use the default implementation which simply * calls the pure virtual version. */ virtual void enqueue(mailbox_element_ptr what, execution_unit* host); /** * Returns the ID of the node this actor is running on. */ inline node_id node() const { return m_node; } /** * Returns true if {@link node_ptr} returns */ bool is_remote() const; static constexpr int is_abstract_actor_flag = 0x100000; static constexpr int is_abstract_group_flag = 0x200000; inline bool is_abstract_actor() const { return static_cast(flags() & is_abstract_actor_flag); } inline bool is_abstract_group() const { return static_cast(flags() & is_abstract_group_flag); } protected: // note: *both* operations use relaxed memory order, this is because // only the actor itself is granted write access while all access // from other actors or threads is always read-only; further, only // flags that are considered constant after an actor has launched are // read by others, i.e., there is no acquire/release semantic between // setting and reading flags inline int flags() const { return m_flags.load(std::memory_order_relaxed); } inline void flags(int new_value) { m_flags.store(new_value, std::memory_order_relaxed); } private: // can only be called from abstract_actor and abstract_group abstract_channel(int init_flags); abstract_channel(int init_flags, node_id nid); /* * Accumulates several state and type flags. Subtypes may use only the * first 20 bits, i.e., the bitmask 0xFFF00000 is reserved for * channel-related flags. */ std::atomic m_flags; // identifies the node of this channel node_id m_node; }; /** * A smart pointer to an abstract channel. * @relates abstract_channel_ptr */ using abstract_channel_ptr = intrusive_ptr; } // namespace caf #endif // CAF_ABSTRACT_CHANNEL_HPP actor-framework-0.13.2/libcaf_core/caf/abstract_event_based_actor.hpp000066400000000000000000000067531251275671500257520ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_ABSTRACT_EVENT_BASED_ACTOR_HPP #define CAF_ABSTRACT_EVENT_BASED_ACTOR_HPP #include #include "caf/message_id.hpp" #include "caf/local_actor.hpp" #include "caf/typed_behavior.hpp" #include "caf/behavior_policy.hpp" #include "caf/response_handle.hpp" #include "caf/mixin/sync_sender.hpp" namespace caf { /* * Base type for typed and untyped event-based actors. * @tparam BehaviorType Denotes the expected type for become(). * @tparam HasSyncSend Configures whether this base class extends `sync_sender`. * @extends local_actor */ template class abstract_event_based_actor : public std::conditional< HasSyncSend, extend ::with::template impl>, local_actor >::type { public: using behavior_type = BehaviorType; /**************************************************************************** * become() member function family * ****************************************************************************/ void become(behavior_type bhvr) { this->do_become(std::move(unbox(bhvr)), true); } void become(const keep_behavior_t&, behavior_type bhvr) { this->do_become(std::move(unbox(bhvr)), false); } template typename std::enable_if< !std::is_same::type>::value, void >::type become(T&& x, Ts&&... xs) { behavior_type bhvr{std::forward(x), std::forward(xs)...}; this->do_become(std::move(unbox(bhvr)), true); } template void become(const keep_behavior_t&, Ts&&... xs) { behavior_type bhvr{std::forward(xs)...}; this->do_become(std::move(unbox(bhvr)), false); } void unbecome() { this->m_bhvr_stack.pop_back(); } private: template static behavior& unbox(typed_behavior& x) { return x.unbox(); } static inline behavior& unbox(behavior& x) { return x; } }; } // namespace caf #endif // CAF_ABSTRACT_EVENT_BASED_ACTOR_HPP actor-framework-0.13.2/libcaf_core/caf/abstract_group.hpp000066400000000000000000000116611251275671500234310ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_ABSTRACT_GROUP_HPP #define CAF_ABSTRACT_GROUP_HPP #include #include #include "caf/actor_addr.hpp" #include "caf/attachable.hpp" #include "caf/ref_counted.hpp" #include "caf/abstract_channel.hpp" namespace caf { namespace detail { class group_manager; class peer_connection; } // namespace detail } // namespace caf namespace caf { class group; class serializer; class local_actor; class deserializer; /** * A multicast group. */ class abstract_group : public abstract_channel { public: friend class detail::group_manager; friend class detail::peer_connection; friend class local_actor; ~abstract_group(); class subscription; struct subscription_token { intrusive_ptr group; static constexpr size_t token_type = attachable::token::subscription; }; class subscription_predicate { public: inline subscription_predicate(intrusive_ptr group) : m_group(std::move(group)) { // nop } inline bool operator()(const attachable_ptr& ptr) { return ptr->matches(subscription_token{m_group}); } private: intrusive_ptr m_group; }; // needs access to unsubscribe() friend class subscription; // unsubscribes its channel from the group on destruction class subscription : public attachable { public: subscription(const intrusive_ptr& g); void actor_exited(abstract_actor* self, uint32_t reason) override; bool matches(const token& what) override; static inline attachable_ptr make(intrusive_ptr ptr) { return attachable_ptr{new subscription(std::move(ptr))}; } const intrusive_ptr& group() const { return m_group; } private: intrusive_ptr m_group; }; /** * Interface for user-defined multicast implementations. */ class module { public: module(std::string module_name); virtual ~module(); /** * Stops all groups from this module. */ virtual void stop() = 0; /** * Returns the name of this module implementation. * @threadsafe */ const std::string& name(); /** * Returns a pointer to the group associated with the name `group_name`. * @threadsafe */ virtual group get(const std::string& group_name) = 0; virtual group deserialize(deserializer* source) = 0; private: std::string m_name; }; using module_ptr = module*; using unique_module_ptr = std::unique_ptr; virtual void serialize(serializer* sink) = 0; /** * Returns a string representation of the group identifier, e.g., * "224.0.0.1" for IPv4 multicast or a user-defined string for local groups. */ const std::string& identifier() const; module_ptr get_module() const; /** * Returns the name of the module. */ const std::string& module_name() const; /** * Subscribes `who` to this group and returns a subscription object. */ virtual attachable_ptr subscribe(const actor_addr& who) = 0; /** * Stops any background actors or threads and IO handles. */ virtual void stop() = 0; protected: abstract_group(module_ptr module, std::string group_id); // called by subscription objects virtual void unsubscribe(const actor_addr& who) = 0; module_ptr m_module; std::string m_identifier; }; /** * A smart pointer type that manages instances of {@link group}. * @relates group */ using abstract_group_ptr = intrusive_ptr; } // namespace caf #endif // CAF_ABSTRACT_GROUP_HPP actor-framework-0.13.2/libcaf_core/caf/actor.hpp000066400000000000000000000115751251275671500215260ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_ACTOR_HPP #define CAF_ACTOR_HPP #include #include #include #include #include "caf/intrusive_ptr.hpp" #include "caf/fwd.hpp" #include "caf/abstract_actor.hpp" #include "caf/detail/comparable.hpp" #include "caf/detail/type_traits.hpp" namespace caf { class scoped_actor; struct invalid_actor_t { constexpr invalid_actor_t() {} }; /** * Identifies an invalid {@link actor}. * @relates actor */ constexpr invalid_actor_t invalid_actor = invalid_actor_t{}; template struct is_convertible_to_actor { using type = typename std::remove_pointer::type; static constexpr bool value = std::is_base_of::value || std::is_base_of::value || std::is_same::value; }; /** * Identifies an untyped actor. Can be used with derived types * of `event_based_actor`, `blocking_actor`, and `actor_proxy`. */ class actor : detail::comparable, detail::comparable, detail::comparable, detail::comparable { friend class local_actor; template friend T actor_cast(const U&); public: actor() = default; actor(actor&&) = default; actor(const actor&) = default; template actor(intrusive_ptr ptr, typename std::enable_if::value>::type* = 0) : m_ptr(std::move(ptr)) {} template actor(T* ptr, typename std::enable_if::value>::type* = 0) : m_ptr(ptr) {} actor(const invalid_actor_t&); actor& operator=(actor&&) = default; actor& operator=(const actor&) = default; template typename std::enable_if::value, actor&>::type operator=(intrusive_ptr ptr) { actor tmp{std::move(ptr)}; swap(tmp); return *this; } template typename std::enable_if::value, actor&>::type operator=(T* ptr) { actor tmp{ptr}; swap(tmp); return *this; } actor& operator=(const invalid_actor_t&); inline operator bool() const { return static_cast(m_ptr); } inline bool operator!() const { return !m_ptr; } /** * Returns a handle that grants access to actor operations such as enqueue. */ inline abstract_actor* operator->() const { return m_ptr.get(); } inline abstract_actor& operator*() const { return *m_ptr; } intptr_t compare(const actor& other) const; intptr_t compare(const actor_addr&) const; inline intptr_t compare(const invalid_actor_t&) const { return m_ptr ? 1 : 0; } inline intptr_t compare(const invalid_actor_addr_t&) const { return compare(invalid_actor); } /** * Returns the address of the stored actor. */ actor_addr address() const; /** * Returns whether this is an handle to a remote actor. */ bool is_remote() const; actor_id id() const; void swap(actor& other); private: inline abstract_actor* get() const { return m_ptr.get(); } actor(abstract_actor*); abstract_actor_ptr m_ptr; }; } // namespace caf // allow actor to be used in hash maps namespace std { template <> struct hash { inline size_t operator()(const caf::actor& ref) const { return ref ? static_cast(ref->id()) : 0; } }; } // namespace std #endif // CAF_ACTOR_HPP actor-framework-0.13.2/libcaf_core/caf/actor_addr.hpp000066400000000000000000000072201251275671500225100ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_ACTOR_ADDR_HPP #define CAF_ACTOR_ADDR_HPP #include #include #include #include #include "caf/intrusive_ptr.hpp" #include "caf/fwd.hpp" #include "caf/abstract_actor.hpp" #include "caf/detail/comparable.hpp" namespace caf { struct invalid_actor_addr_t { constexpr invalid_actor_addr_t() {} }; /** * Identifies an invalid {@link actor_addr}. * @relates actor_addr */ constexpr invalid_actor_addr_t invalid_actor_addr = invalid_actor_addr_t{}; /** * Stores the address of typed as well as untyped actors. */ class actor_addr : detail::comparable, detail::comparable, detail::comparable { friend class actor; friend class abstract_actor; template friend T actor_cast(const U&); public: actor_addr() = default; actor_addr(actor_addr&&) = default; actor_addr(const actor_addr&) = default; actor_addr& operator=(actor_addr&&) = default; actor_addr& operator=(const actor_addr&) = default; actor_addr(const invalid_actor_addr_t&); actor_addr operator=(const invalid_actor_addr_t&); inline explicit operator bool() const { return static_cast(m_ptr); } inline bool operator!() const { return !m_ptr; } intptr_t compare(const actor_addr& other) const; intptr_t compare(const abstract_actor* other) const; inline intptr_t compare(const abstract_actor_ptr& other) const { return compare(other.get()); } actor_id id() const; node_id node() const; /** * Returns whether this is an address of a remote actor. */ bool is_remote() const; /** * Returns the set of accepted messages types as strings or * an empty set if this actor is untyped. */ std::set message_types() const; private: inline abstract_actor* get() const { return m_ptr.get(); } explicit actor_addr(abstract_actor*); abstract_actor_ptr m_ptr; }; } // namespace caf // allow actor_addr to be used in hash maps namespace std { template <> struct hash { inline size_t operator()(const caf::actor_addr& ref) const { return static_cast(ref.id()); } }; } // namespace std #endif // CAF_ACTOR_ADDR_HPP actor-framework-0.13.2/libcaf_core/caf/actor_cast.hpp000066400000000000000000000033011251275671500225240ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_ACTOR_CAST_HPP #define CAF_ACTOR_CAST_HPP namespace caf { /** * Converts actor handle `what` to a different actor handle of type `T`. */ template T actor_cast(const U& what) { return what.get(); } } // namespace caf #endif // CAF_ACTOR_CAST_HPP actor-framework-0.13.2/libcaf_core/caf/actor_companion.hpp000066400000000000000000000061361251275671500235660ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_ACTOR_COMPANION_HPP #define CAF_ACTOR_COMPANION_HPP #include #include #include "caf/local_actor.hpp" #include "caf/mailbox_element.hpp" #include "caf/abstract_event_based_actor.hpp" #include "caf/mixin/sync_sender.hpp" #include "caf/detail/disposer.hpp" #include "caf/detail/shared_spinlock.hpp" namespace caf { /** * An co-existing forwarding all messages through a user-defined * callback to another object, thus serving as gateway to * allow any object to interact with other actors. * @extends local_actor */ class actor_companion : public abstract_event_based_actor { public: using lock_type = detail::shared_spinlock; using message_pointer = std::unique_ptr; using enqueue_handler = std::function; /** * Removes the handler for incoming messages and terminates * the companion for exit reason @ rsn. */ void disconnect(std::uint32_t rsn = exit_reason::normal); /** * Sets the handler for incoming messages. * @warning `handler` needs to be thread-safe */ void on_enqueue(enqueue_handler handler); void enqueue(mailbox_element_ptr what, execution_unit* host) override; void enqueue(const actor_addr& sender, message_id mid, message content, execution_unit* host) override; void initialize(); private: // set by parent to define custom enqueue action enqueue_handler m_on_enqueue; // guards access to m_handler lock_type m_lock; }; /** * A pointer to a co-existing (actor) object. * @relates actor_companion */ using actor_companion_ptr = intrusive_ptr; } // namespace caf #endif // CAF_ACTOR_COMPANION_HPP actor-framework-0.13.2/libcaf_core/caf/actor_namespace.hpp000066400000000000000000000073521251275671500235400ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_ACTOR_NAMESPACE_HPP #define CAF_ACTOR_NAMESPACE_HPP #include #include #include #include "caf/node_id.hpp" #include "caf/actor_cast.hpp" #include "caf/actor_proxy.hpp" namespace caf { class serializer; class deserializer; /** * Groups a (distributed) set of actors and allows actors * in the same namespace to exchange messages. */ class actor_namespace { public: using key_type = node_id; /** * The backend of an actor namespace is responsible for creating proxy actors. */ class backend { public: virtual ~backend(); /** * Creates a new proxy instance. */ virtual actor_proxy_ptr make_proxy(const key_type&, actor_id) = 0; }; actor_namespace(backend& mgm); /** * Writes an actor address to `sink` and adds the actor * to the list of known actors for a later deserialization. */ void write(serializer* sink, const actor_addr& ptr); /** * Reads an actor address from `source,` creating * addresses for remote actors on the fly if needed. */ actor_addr read(deserializer* source); /** * A map that stores all proxies for known remote actors. */ using proxy_map = std::map; /** * Returns the number of proxies for `node`. */ size_t count_proxies(const key_type& node); /** * Returns all proxies for `node`. */ std::vector get_all(); /** * Returns all proxies for `node`. */ std::vector get_all(const key_type& node); /** * Returns the proxy instance identified by `node` and `aid` * or `nullptr` if the actor either unknown or expired. */ actor_proxy_ptr get(const key_type& node, actor_id aid); /** * Returns the proxy instance identified by `node` and `aid` * or creates a new (default) proxy instance. */ actor_proxy_ptr get_or_put(const key_type& node, actor_id aid); /** * Deletes all proxies for `node`. */ void erase(const key_type& node); /** * Deletes the proxy with id `aid` for `node`. */ void erase(const key_type& node, actor_id aid); /** * Queries whether there are any proxies left. */ bool empty() const; /** * Deletes all proxies. */ void clear(); private: backend& m_backend; std::map m_proxies; }; } // namespace caf #endif actor-framework-0.13.2/libcaf_core/caf/actor_ostream.hpp000066400000000000000000000060741251275671500232560ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_ACTOR_OSTREAM_HPP #define CAF_ACTOR_OSTREAM_HPP #include "caf/actor.hpp" #include "caf/message.hpp" #include "caf/to_string.hpp" namespace caf { class local_actor; class scoped_actor; class actor_ostream { public: using fun_type = actor_ostream& (*)(actor_ostream&); actor_ostream(actor_ostream&&) = default; actor_ostream(const actor_ostream&) = default; actor_ostream& operator=(actor_ostream&&) = default; actor_ostream& operator=(const actor_ostream&) = default; explicit actor_ostream(actor self); actor_ostream& write(std::string arg); actor_ostream& flush(); inline actor_ostream& operator<<(std::string arg) { return write(std::move(arg)); } inline actor_ostream& operator<<(const message& arg) { return write(caf::to_string(arg)); } // disambiguate between conversion to string and to message inline actor_ostream& operator<<(const char* arg) { return *this << std::string{arg}; } template inline typename std::enable_if< !std::is_convertible::value && !std::is_convertible::value, actor_ostream& >::type operator<<(T&& arg) { return write(std::to_string(std::forward(arg))); } inline actor_ostream& operator<<(actor_ostream::fun_type f) { return f(*this); } private: actor m_self; actor m_printer; }; inline actor_ostream aout(actor self) { return actor_ostream{self}; } } // namespace caf namespace std { // provide convenience overlaods for aout; implemented in logging.cpp caf::actor_ostream& endl(caf::actor_ostream& o); caf::actor_ostream& flush(caf::actor_ostream& o); } // namespace std #endif // CAF_ACTOR_OSTREAM_HPP actor-framework-0.13.2/libcaf_core/caf/actor_pool.hpp000066400000000000000000000131711251275671500225510ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_ACTOR_POOL_HPP #define CAF_ACTOR_POOL_HPP #include #include #include #include #include "caf/locks.hpp" #include "caf/actor.hpp" #include "caf/abstract_actor.hpp" #include "caf/mailbox_element.hpp" #include "caf/detail/split_join.hpp" #include "caf/detail/shared_spinlock.hpp" namespace caf { /** * An actor poool is a lightweight abstraction for a set of workers. * The pool itself is an actor, meaning that it can be passed * around in an actor system to hide the actual set of workers. * * After construction, new workers can be added via `{'SYS', 'PUT', actor}` * messages, e.g., `send(my_pool, sys_atom::value, put_atom::value, worker)`. * `{'SYS', 'DELETE', actor}` messages remove a worker from the set, * whereas `{'SYS', 'GET'}` returns a `vector` containing all workers. * * Note that the pool *always* sends exit messages to all of its workers * when forced to quit. The pool monitors all of its workers. Messages queued * up in a worker's mailbox are lost, i.e., the pool itself does not buffer * and resend messages. Advanced caching or resend strategies can be * implemented in a policy. * * It is wort mentioning that the pool is *not* an event-based actor. * Neither does it live in its own thread. Messages are dispatched immediately * during the enqueue operation. Any user-defined policy thus has to dispatch * messages with as little overhead as possible, because the dispatching * runs in the context of the sender. */ class actor_pool : public abstract_actor { public: using uplock = upgrade_lock; using actor_vec = std::vector; using factory = std::function; using policy = std::function; /** * Default policy class implementing simple round robin dispatching. */ class round_robin { public: round_robin(); round_robin(const round_robin&); void operator()(uplock&, const actor_vec&, mailbox_element_ptr&, execution_unit*); private: std::atomic m_pos; }; /** * Default policy class implementing broadcast dispatching. */ class broadcast { public: void operator()(uplock&, const actor_vec&, mailbox_element_ptr&, execution_unit*); }; /** * Default policy class implementing random dispatching. */ class random { public: random(); random(const random&); void operator()(uplock&, const actor_vec&, mailbox_element_ptr&, execution_unit*); private: std::random_device m_rd; }; /** * Default policy class implementing broadcast dispatching (split step) * followed by a join operation `F` combining all individual results to * a single result of type `T`. * @tparam T Result type received by the original sender. * @tparam Join Functor with signature `void (T&, message&)`. * @tparam Split Functor with signature * `void (vector>&, message&)`. */ template static policy split_join(Join jf, Split sf = Split(), T init = T()) { using impl = detail::split_join; return impl{std::move(init), std::move(sf), std::move(jf)}; } ~actor_pool(); /** * Returns an actor pool without workers using the dispatch policy `pol`. */ static actor make(policy pol); /** * Returns an actor pool with `n` workers created by the factory * function `fac` using the dispatch policy `pol`. */ static actor make(size_t n, factory fac, policy pol); void enqueue(const actor_addr& sender, message_id mid, message content, execution_unit* host) override; void enqueue(mailbox_element_ptr what, execution_unit* host) override; actor_pool(); private: bool filter(upgrade_lock&, const actor_addr& sender, message_id mid, const message& content, execution_unit* host); // call without m_mtx held void quit(); detail::shared_spinlock m_mtx; std::vector m_workers; policy m_policy; uint32_t m_planned_reason; }; } // namespace caf #endif // CAF_ACTOR_POOL_HPP actor-framework-0.13.2/libcaf_core/caf/actor_proxy.hpp000066400000000000000000000064651251275671500227710ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_ACTOR_PROXY_HPP #define CAF_ACTOR_PROXY_HPP #include #include #include "caf/abstract_actor.hpp" #include "caf/detail/shared_spinlock.hpp" namespace caf { class actor_proxy; /** * A smart pointer to an {@link actor_proxy} instance. * @relates actor_proxy */ using actor_proxy_ptr = intrusive_ptr; /** * Represents an actor running on a remote machine, * or different hardware, or in a separate process. */ class actor_proxy : public abstract_actor { public: /** * An anchor points to a proxy instance without sharing * ownership to it, i.e., models a weak ptr. */ class anchor : public ref_counted { public: friend class actor_proxy; anchor(actor_proxy* instance = nullptr); ~anchor(); /** * Queries whether the proxy was already deleted. */ bool expired() const; /** * Gets a pointer to the proxy or `nullptr` * if the instance is {@link expired()}. */ actor_proxy_ptr get(); private: /* * Tries to expire this anchor. Fails if reference * count of the proxy is nonzero. */ bool try_expire() noexcept; std::atomic m_ptr; detail::shared_spinlock m_lock; }; using anchor_ptr = intrusive_ptr; ~actor_proxy(); /** * Establishes a local link state that's not synchronized back * to the remote instance. */ virtual void local_link_to(const actor_addr& other) = 0; /** * Removes a local link state. */ virtual void local_unlink_from(const actor_addr& other) = 0; /** * Invokes cleanup code. */ virtual void kill_proxy(uint32_t reason) = 0; void request_deletion(bool decremented_ref_count) noexcept override; inline anchor_ptr get_anchor() { return m_anchor; } protected: actor_proxy(actor_id aid, node_id nid); anchor_ptr m_anchor; }; } // namespace caf #endif // CAF_ACTOR_PROXY_HPP actor-framework-0.13.2/libcaf_core/caf/all.hpp000066400000000000000000000301171251275671500211570ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_ALL_HPP #define CAF_ALL_HPP #include "caf/on.hpp" #include "caf/atom.hpp" #include "caf/send.hpp" #include "caf/unit.hpp" #include "caf/actor.hpp" #include "caf/group.hpp" #include "caf/spawn.hpp" #include "caf/config.hpp" #include "caf/either.hpp" #include "caf/extend.hpp" #include "caf/channel.hpp" #include "caf/message.hpp" #include "caf/node_id.hpp" #include "caf/announce.hpp" #include "caf/anything.hpp" #include "caf/behavior.hpp" #include "caf/duration.hpp" #include "caf/sb_actor.hpp" #include "caf/shutdown.hpp" #include "caf/exception.hpp" #include "caf/resumable.hpp" #include "caf/scheduler.hpp" #include "caf/spawn_fwd.hpp" #include "caf/to_string.hpp" #include "caf/actor_addr.hpp" #include "caf/actor_pool.hpp" #include "caf/attachable.hpp" #include "caf/message_id.hpp" #include "caf/replies_to.hpp" #include "caf/serializer.hpp" #include "caf/actor_proxy.hpp" #include "caf/exit_reason.hpp" #include "caf/from_string.hpp" #include "caf/local_actor.hpp" #include "caf/ref_counted.hpp" #include "caf/typed_actor.hpp" #include "caf/deserializer.hpp" #include "caf/scoped_actor.hpp" #include "caf/skip_message.hpp" #include "caf/actor_ostream.hpp" #include "caf/spawn_options.hpp" #include "caf/abstract_actor.hpp" #include "caf/abstract_group.hpp" #include "caf/blocking_actor.hpp" #include "caf/execution_unit.hpp" #include "caf/memory_managed.hpp" #include "caf/typed_behavior.hpp" #include "caf/actor_namespace.hpp" #include "caf/behavior_policy.hpp" #include "caf/continue_helper.hpp" #include "caf/mailbox_element.hpp" #include "caf/message_builder.hpp" #include "caf/message_handler.hpp" #include "caf/response_handle.hpp" #include "caf/system_messages.hpp" #include "caf/abstract_channel.hpp" #include "caf/may_have_timeout.hpp" #include "caf/message_priority.hpp" #include "caf/response_promise.hpp" #include "caf/binary_serializer.hpp" #include "caf/event_based_actor.hpp" #include "caf/primitive_variant.hpp" #include "caf/uniform_type_info.hpp" #include "caf/timeout_definition.hpp" #include "caf/binary_deserializer.hpp" #include "caf/await_all_actors_done.hpp" #include "caf/typed_continue_helper.hpp" #include "caf/typed_event_based_actor.hpp" /** * @author Dominik Charousset * * @mainpage libcaf * * @section Intro Introduction * * This library provides an implementation of the actor model for C++. * It uses a network transparent messaging system to ease development * of both concurrent and distributed software. * * `libcaf` uses a thread pool to schedule actors by default. * A scheduled actor should not call blocking functions. * Individual actors can be spawned (created) with a special flag to run in * an own thread if one needs to make use of blocking APIs. * * Writing applications in `libcaf` requires a minimum of gluecode and * each context is an actor. Even main is implicitly * converted to an actor if needed. * * @section GettingStarted Getting Started * * To build `libcaf,` you need `GCC >= 4.7 or Clang >= *3.2, * and `CMake`. * * The usual build steps on Linux and Mac OS X are: * *- `mkdir build *- `cd build *- `cmake .. *- `make *- `make install (as root, optionally) * * Please run the unit tests as well to verify that `libcaf` * works properly. * *- `./bin/unit_tests * * Please submit a bug report that includes (a) your compiler version, * (b) your OS, and (c) the output of the unit tests if an error occurs. * * Windows is not supported yet, because MVSC++ doesn't implement the * C++11 features needed to compile `libcaf`. * * Please read the Manual for an introduction to `libcaf`. * It is available online as HTML at * http://neverlord.github.com/libcaf/manual/index.html or as PDF at * http://neverlord.github.com/libcaf/manual/manual.pdf * * @section IntroHelloWorld Hello World Example * * @include hello_world.cpp * * @section IntroMoreExamples More Examples * * The {@link math_actor.cpp Math Actor Example} shows the usage * of {@link receive_loop} and {@link caf::arg_match arg_match}. * The {@link dining_philosophers.cpp Dining Philosophers Example} * introduces event-based actors and includes a lot of `libcaf * features. * * @namespace caf * Root namespace of libcaf. * * @namespace caf::mixin * Contains mixin classes implementing several actor traits. * * @namespace caf::exit_reason * Contains all predefined exit reasons. * * @namespace caf::policy * Contains policies encapsulating characteristics or algorithms. * * @namespace caf::io * Contains all network-related classes and functions. * * @defgroup MessageHandling Message handling. * * This is the beating heart of `libcaf`. Actor programming is * all about message handling. * * A message in `libcaf` is a n-tuple of values (with size >= 1) * You can use almost every type in a messages - as long as it is announced, * i.e., known by the type system of `libcaf`. * * @defgroup BlockingAPI Blocking API. * * Blocking functions to receive messages. * * The blocking API of libcaf is intended to be used for migrating * previously threaded applications. When writing new code, you should use * ibcafs nonblocking become/unbecome API. * * @section Send Send messages * * The function `send` can be used to send a message to an actor. * The first argument is the receiver of the message followed by any number * of values: * * @code * // spawn some actors * auto a1 = spawn(...); * auto a2 = spawn(...); * auto a3 = spawn(...); * * // send a message to a1 * send(a1, atom("hello"), "hello a1!"); * * // send a message to a1, a2, and a3 * auto msg = make_message(atom("compute"), 1, 2, 3); * send(a1, msg); * send(a2, msg); * send(a3, msg); * @endcode * * @section Receive Receive messages * * The function `receive` takes a `behavior` as argument. The behavior * is a list of { pattern >> callback } rules. * * @code * receive * ( * on(atom("hello"), arg_match) >> [](const std::string& msg) * { * cout << "received hello message: " << msg << endl; * }, * on(atom("compute"), arg_match) >> [](int i0, int i1, int i2) * { * // send our result back to the sender of this messages * return make_message(atom("result"), i0 + i1 + i2); * } * ); * @endcode * * Please read the manual for further details about pattern matching. * * @section Atoms Atoms * * Atoms are a nice way to add semantic informations to a message. * Assuming an actor wants to provide a "math sevice" for integers. It * could provide operations such as addition, subtraction, etc. * This operations all have two operands. Thus, the actor does not know * what operation the sender of a message wanted by receiving just two integers. * * Example actor: * @code * void math_actor() { * receive_loop ( * on(atom("plus"), arg_match) >> [](int a, int b) { * return make_message(atom("result"), a + b); * }, * on(atom("minus"), arg_match) >> [](int a, int b) { * return make_message(atom("result"), a - b); * } * ); * } * @endcode * * @section ReceiveLoops Receive loops * * Previous examples using `receive` create behaviors on-the-fly. * This is inefficient in a loop since the argument passed to receive * is created in each iteration again. It's possible to store the behavior * in a variable and pass that variable to receive. This fixes the issue * of re-creation each iteration but rips apart definition and usage. * * There are four convenience functions implementing receive loops to * declare behavior where it belongs without unnecessary * copies: `receive_loop,` `receive_while,` `receive_for` and `do_receive`. * * `receive_loop` is analogous to `receive` and loops "forever" (until the * actor finishes execution). * * `receive_while` creates a functor evaluating a lambda expression. * The loop continues until the given lambda returns `false`. A simple example: * * @code * // receive two integers * vector received_values; * receive_while([&]() { return received_values.size() < 2; }) ( * on() >> [](int value) { * received_values.push_back(value); * } * ); * // ... * @endcode * * `receive_for` is a simple ranged-based loop: * * @code * std::vector vec {1, 2, 3, 4}; * auto i = vec.begin(); * receive_for(i, vec.end()) ( * on(atom("get")) >> [&]() -> message { return {atom("result"), *i}; } * ); * @endcode * * `do_receive` returns a functor providing the function `until` that * takes a lambda expression. The loop continues until the given lambda * returns true. Example: * * @code * // receive ints until zero was received * vector received_values; * do_receive ( * on() >> [](int value) { * received_values.push_back(value); * } * ) * .until([&]() { return received_values.back() == 0 }); * // ... * @endcode * * @section FutureSend Send delayed messages * * The function `delayed_send` provides a simple way to delay a message. * This is particularly useful for recurring events, e.g., periodical polling. * Usage example: * * @code * delayed_send(self, std::chrono::seconds(1), atom("poll")); * receive_loop ( * // ... * on(atom("poll")) >> [] { * // ... poll something ... * // and do it again after 1sec * delayed_send(self, std::chrono::seconds(1), atom("poll")); * } * ); * @endcode * * See also the {@link dancing_kirby.cpp dancing kirby example}. * * @defgroup ImplicitConversion Implicit type conversions. * * The message passing of `libcaf` prohibits pointers in messages because * it enforces network transparent messaging. * Unfortunately, string literals in `C++` have the type `const char*, * resp. `const char[]. Since `libcaf` is a user-friendly library, * it silently converts string literals and C-strings to `std::string` objects. * It also converts unicode literals to the corresponding STL container. * * A few examples: * @code * // sends an std::string containing "hello actor!" to itself * send(self, "hello actor!"); * * const char* cstring = "cstring"; * // sends an std::string containing "cstring" to itself * send(self, cstring); * * // sends an std::u16string containing the UTF16 string "hello unicode world!" * send(self, u"hello unicode world!"); * * // x has the type caf::tuple * auto x = make_message("hello", "tuple"); * * receive ( * // equal to: on(std::string("hello actor!")) * on("hello actor!") >> [] { } * ); * @endcode * * @defgroup ActorCreation Actor creation. */ // examples /** * A trivial example program. * @example hello_world.cpp */ /** * A simple example for a delayed_send based application. * @example dancing_kirby.cpp */ /** * An event-based "Dining Philosophers" implementation. * @example dining_philosophers.cpp */ #endif // CAF_ALL_HPP actor-framework-0.13.2/libcaf_core/caf/announce.hpp000066400000000000000000000122571251275671500222220ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_ANNOUNCE_HPP #define CAF_ANNOUNCE_HPP #include #include #include "caf/string_algorithms.hpp" #include "caf/config.hpp" #include "caf/uniform_type_info.hpp" #include "caf/detail/abstract_uniform_type_info.hpp" #include "caf/detail/safe_equal.hpp" #include "caf/detail/default_uniform_type_info.hpp" namespace caf { /** * @addtogroup TypeSystem * @{ */ /** * A simple example for announce with public accessible members. * The output of this example program is: * > foo(1, 2)
* > foo_pair(3, 4) * @example announce_1.cpp */ /** * An example for announce with getter and setter member functions. * The output of this example program is: * * > foo(1, 2) * @example announce_2.cpp */ /** * An example for announce with overloaded getter and setter member functions. * The output of this example program is: * * > foo(1, 2) * @example announce_3.cpp */ /** * An example for announce with non-primitive members. * The output of this example program is: * * > bar(foo(1, 2), 3) * @example announce_4.cpp */ /** * An advanced example for announce implementing serialization * for a user-defined tree data type. * @example announce_5.cpp */ /** * Adds a new mapping to the type system. Returns `utype.get()` on * success, otherwise a pointer to the previously installed singleton. * @warning `announce` is **not** thead-safe! */ const uniform_type_info* announce(const std::type_info& tinfo, uniform_type_info_ptr utype); // deals with member pointer /** * Creates meta information for a non-trivial `Member`, * whereas `xs` are the "sub-members" of `Member`. * @see {@link announce_4.cpp announce example 4} */ template std::pair*> compound_member(Member Parent::*memptr, const Ts&... xs) { return {memptr, new detail::default_uniform_type_info("???", xs...)}; } // deals with getter returning a mutable reference /** * Creates meta information for a non-trivial `Member` accessed * via the getter member function `getter` returning a mutable reference, * whereas `xs` are the "sub-members" of `Member`. * @see {@link announce_4.cpp announce example 4} */ template std::pair*> compound_member(Member& (Parent::*getter)(), const Ts&... xs) { return {getter, new detail::default_uniform_type_info("???", xs...)}; } // deals with getter/setter pair /** * Creates meta information for a non-trivial `Member` accessed * via the pair of getter and setter member function pointers `gspair`, * whereas `xs` are the "sub-members" of `Member`. * @see {@link announce_4.cpp announce example 4} */ template std::pair, detail::abstract_uniform_type_info::type>*> compound_member(const std::pair& gspair, const Ts&... xs) { using mtype = typename std::decay::type; return {gspair, new detail::default_uniform_type_info("???", xs...)}; } /** * Adds a new type mapping for `T` to the type system using `tname` * as its uniform name and the list of member pointers `xs`. * @warning `announce` is **not** thead-safe! */ template inline const uniform_type_info* announce(std::string tname, const Ts&... xs) { auto ptr = new detail::default_uniform_type_info(std::move(tname), xs...); return announce(typeid(T), uniform_type_info_ptr{ptr}); } /** * @} */ } // namespace caf #endif // CAF_ANNOUNCE_HPP actor-framework-0.13.2/libcaf_core/caf/anything.hpp000066400000000000000000000037211251275671500222310ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_ANYTHING_HPP #define CAF_ANYTHING_HPP #include namespace caf { /** * Acts as wildcard expression in patterns. */ struct anything { // no content }; /** * @relates anything */ inline bool operator==(const anything&, const anything&) { return true; } /** * @relates anything */ inline bool operator!=(const anything&, const anything&) { return false; } /** * @relates anything */ template struct is_anything : std::is_same { // no content }; } // namespace caf #endif // CAF_ANYTHING_HPP actor-framework-0.13.2/libcaf_core/caf/atom.hpp000066400000000000000000000071461251275671500213550ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_ATOM_HPP #define CAF_ATOM_HPP #include #include #include "caf/detail/atom_val.hpp" namespace caf { /** * The value type of atoms. */ enum class atom_value : uint64_t { /** @cond PRIVATE */ dirty_little_hack = 31337 /** @endcond */ }; /** * Creates an atom from given string literal. */ template constexpr atom_value atom(char const (&str)[Size]) { // last character is the NULL terminator static_assert(Size <= 11, "only 10 characters are allowed"); return static_cast(detail::atom_val(str, 0xF)); } /** * Lifts an `atom_value` to a compile-time constant. */ template struct atom_constant { constexpr atom_constant() { // nop } /** * Returns the wrapped value. */ constexpr operator atom_value() const { return V; } /** * Returns an instance *of this constant* (*not* an `atom_value`). */ static const atom_constant value; }; template const atom_constant atom_constant::value = atom_constant{}; /** * Generic 'GET' atom for request operations. */ using get_atom = atom_constant; /** * Generic 'PUT' atom for request operations. */ using put_atom = atom_constant; /** * Generic 'DELETE' atom for request operations. */ using delete_atom = atom_constant; /** * Generic 'OK' atom for response messages. */ using ok_atom = atom_constant; /** * Generic 'ERROR' atom for response messages. */ using error_atom = atom_constant; /** * Marker 'SYS' atom for prefixing messages to a forwarding chain * to address an otherwise transparent actor. */ using sys_atom = atom_constant; /** * Generic 'JOIN' atom, e.g., for signaling group subscriptions. */ using join_atom = atom_constant; /** * Generic 'LEAVE' atom, e.g., for signaling group unsubscriptions. */ using leave_atom = atom_constant; /** * Generic 'FORWARD' atom, e.g., for signaling an actor that it * should drop the first element and forward the remainder to * a list of predefined receivers. */ using forward_atom = atom_constant; } // namespace caf #endif // CAF_ATOM_HPP actor-framework-0.13.2/libcaf_core/caf/attachable.hpp000066400000000000000000000071141251275671500225000ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_ATTACHABLE_HPP #define CAF_ATTACHABLE_HPP #include #include #include #include #include "caf/optional.hpp" namespace caf { class abstract_actor; /** * Callback utility class. */ class attachable { public: attachable() = default; attachable(const attachable&) = delete; attachable& operator=(const attachable&) = delete; /** * Represents a pointer to a value with its subtype as type ID number. */ struct token { /** * Identifies a non-matchable subtype. */ static constexpr size_t anonymous = 0; /** * Identifies `abstract_group::subscription`. */ static constexpr size_t subscription = 1; /** * Identifies `default_attachable::observe_token`. */ static constexpr size_t observer = 2; template token(const T& tk) : subtype(T::token_type), ptr(&tk) { // nop } /** * Denotes the type of ptr. */ size_t subtype; /** * Any value, used to identify attachable instances. */ const void* ptr; token(size_t subtype, const void* ptr); }; virtual ~attachable(); /** * Executed if the actor did not handle an exception and must * not return `none` if this attachable did handle `eptr`. * Note that the first handler to handle `eptr` "wins" and no other * handler will be invoked. * @returns The exit reason the actor should use. */ virtual optional handle_exception(const std::exception_ptr& eptr); /** * Executed if the actor finished execution with given `reason`. * The default implementation does nothing. */ virtual void actor_exited(abstract_actor* self, uint32_t reason); /** * Returns `true` if `what` selects this instance, otherwise `false`. */ virtual bool matches(const token& what); /** * Returns `true` if `what` selects this instance, otherwise `false`. */ template bool matches(const T& what) { return matches(token{T::token_type, &what}); } std::unique_ptr next; }; /** * @relates attachable */ using attachable_ptr = std::unique_ptr; } // namespace caf #endif // CAF_ATTACHABLE_HPP actor-framework-0.13.2/libcaf_core/caf/await_all_actors_done.hpp000066400000000000000000000037541251275671500247330ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_AWAIT_ALL_ACTORS_DONE_HPP #define CAF_AWAIT_ALL_ACTORS_DONE_HPP #include "caf/detail/singletons.hpp" #include "caf/detail/actor_registry.hpp" namespace caf { /** * Blocks execution of this actor until all other actors finished execution. * @warning This function will cause a deadlock if called from multiple actors. * @warning Do not call this function in cooperatively scheduled actors. */ inline void await_all_actors_done() { detail::singletons::get_actor_registry()->await_running_count_equal(0); } } // namespace caf #endif // CAF_AWAIT_ALL_ACTORS_DONE_HPP actor-framework-0.13.2/libcaf_core/caf/behavior.hpp000066400000000000000000000100431251275671500222020ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_BEHAVIOR_HPP #define CAF_BEHAVIOR_HPP #include #include #include "caf/none.hpp" #include "caf/duration.hpp" #include "caf/timeout_definition.hpp" #include "caf/detail/type_list.hpp" #include "caf/detail/type_traits.hpp" #include "caf/detail/behavior_impl.hpp" namespace caf { class message_handler; /** * Describes the behavior of an actor, i.e., provides a message * handler and an optional timeout. */ class behavior { public: friend class message_handler; behavior() = default; behavior(behavior&&) = default; behavior(const behavior&) = default; behavior& operator=(behavior&&) = default; behavior& operator=(const behavior&) = default; /** * Creates a behavior from `fun` without timeout. */ behavior(const message_handler& fun); /** * The list of arguments can contain match expressions, message handlers, * and up to one timeout (if set, the timeout has to be the last argument). */ template behavior(T x, Ts... xs) { assign(std::move(x), std::move(xs)...); } /** * Creates a behavior from `tdef` without message handler. */ template behavior(timeout_definition tdef) : m_impl(detail::make_behavior(tdef)) { // nop } /** * Assigns new handlers. */ template void assign(Ts... xs) { static_assert(sizeof...(Ts) > 0, "assign() called without arguments"); m_impl = detail::make_behavior(xs...); } void assign(intrusive_ptr ptr) { m_impl.swap(ptr); } /** * Equal to `*this = other`. */ void assign(message_handler other); /** * Equal to `*this = other`. */ void assign(behavior other); /** * Invokes the timeout callback if set. */ inline void handle_timeout() { m_impl->handle_timeout(); } /** * Returns the duration after which receive operations * using this behavior should time out. */ inline const duration& timeout() const { return m_impl->timeout(); } /** * Runs this handler and returns its (optional) result. */ inline optional operator()(message& arg) { return (m_impl) ? m_impl->invoke(arg) : none; } /** * Checks whether this behavior is not empty. */ inline operator bool() const { return static_cast(m_impl); } /** @cond PRIVATE */ using impl_ptr = intrusive_ptr; inline const impl_ptr& as_behavior_impl() const { return m_impl; } inline behavior(impl_ptr ptr) : m_impl(std::move(ptr)) { // nop } /** @endcond */ private: impl_ptr m_impl; }; } // namespace caf #endif // CAF_BEHAVIOR_HPP actor-framework-0.13.2/libcaf_core/caf/behavior_policy.hpp000066400000000000000000000034731251275671500235720ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_BEHAVIOR_POLICY_HPP #define CAF_BEHAVIOR_POLICY_HPP namespace caf { struct keep_behavior_t { constexpr keep_behavior_t() { // nop } }; /** * Policy tag that causes {@link event_based_actor::become} to * keep the current behavior available. * @relates local_actor */ constexpr keep_behavior_t keep_behavior = keep_behavior_t{}; } // namespace caf #endif // CAF_BEHAVIOR_POLICY_HPP actor-framework-0.13.2/libcaf_core/caf/binary_deserializer.hpp000066400000000000000000000051661251275671500244430ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_BINARY_DESERIALIZER_HPP #define CAF_BINARY_DESERIALIZER_HPP #include "caf/deserializer.hpp" namespace caf { /** * Implements the deserializer interface with a binary serialization protocol. */ class binary_deserializer : public deserializer { using super = deserializer; public: binary_deserializer(const void* buf, size_t buf_size, actor_namespace* ns = nullptr); binary_deserializer(const void* begin, const void* m_end, actor_namespace* ns = nullptr); const uniform_type_info* begin_object() override; void end_object() override; size_t begin_sequence() override; void end_sequence() override; void read_value(primitive_variant& storage) override; void read_raw(size_t num_bytes, void* storage) override; /** * Replaces the current read buffer. */ void set_rdbuf(const void* buf, size_t buf_size); /** * Replaces the current read buffer. */ void set_rdbuf(const void* begin, const void* m_end); private: const void* m_pos; const void* m_end; }; template inline binary_deserializer& operator>>(binary_deserializer& lhs, T& rhs) { rhs = lhs.read(); return lhs; } } // namespace caf #endif // CAF_BINARY_DESERIALIZER_HPP actor-framework-0.13.2/libcaf_core/caf/binary_serializer.hpp000066400000000000000000000057301251275671500241270ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_BINARY_SERIALIZER_HPP #define CAF_BINARY_SERIALIZER_HPP #include #include #include #include #include #include "caf/serializer.hpp" #include "caf/primitive_variant.hpp" #include "caf/detail/ieee_754.hpp" #include "caf/detail/type_traits.hpp" namespace caf { /** * Implements the serializer interface with a binary serialization protocol. */ class binary_serializer : public serializer { using super = serializer; public: using write_fun = std::function; /** * Creates a binary serializer writing to given iterator position. */ template binary_serializer(OutIter iter, actor_namespace* ns = nullptr) : super(ns) { struct fun { fun(OutIter pos) : m_pos(pos) {} void operator()(const char* first, const char* last) { m_pos = std::copy(first, last, m_pos); } OutIter m_pos; }; m_out = fun{iter}; } void begin_object(const uniform_type_info* uti) override; void end_object() override; void begin_sequence(size_t list_size) override; void end_sequence() override; void write_value(const primitive_variant& value) override; void write_raw(size_t num_bytes, const void* data) override; private: write_fun m_out; }; template ::value>::type> binary_serializer& operator<<(binary_serializer& bs, const T& value) { bs.write_value(value); return bs; } } // namespace caf #endif // CAF_BINARY_SERIALIZER_HPP actor-framework-0.13.2/libcaf_core/caf/blocking_actor.hpp000066400000000000000000000162011251275671500233650ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_BLOCKING_ACTOR_HPP #define CAF_BLOCKING_ACTOR_HPP #include #include #include "caf/none.hpp" #include "caf/on.hpp" #include "caf/extend.hpp" #include "caf/behavior.hpp" #include "caf/local_actor.hpp" #include "caf/typed_actor.hpp" #include "caf/mailbox_element.hpp" #include "caf/response_handle.hpp" #include "caf/detail/type_traits.hpp" #include "caf/mixin/sync_sender.hpp" namespace caf { /** * A thread-mapped or context-switching actor using a blocking * receive rather than a behavior-stack based message processing. * @extends local_actor */ class blocking_actor : public extend:: with::impl> { public: class functor_based; blocking_actor(); ~blocking_actor(); /************************************************************************** * utility stuff and receive() member function family * **************************************************************************/ using timeout_type = std::chrono::high_resolution_clock::time_point; struct receive_while_helper { std::function m_dq; std::function m_stmt; template void operator()(Ts&&... xs) { static_assert(sizeof...(Ts) > 0, "operator() requires at least one argument"); behavior bhvr{std::forward(xs)...}; while (m_stmt()) m_dq(bhvr); } }; template struct receive_for_helper { std::function m_dq; T& begin; T end; template void operator()(Ts&&... xs) { behavior bhvr{std::forward(xs)...}; for (; begin != end; ++begin) m_dq(bhvr); } }; struct do_receive_helper { std::function m_dq; behavior m_bhvr; template void until(Statement stmt) { do { m_dq(m_bhvr); } while (stmt() == false); } void until(const bool& bvalue) { until([&] { return bvalue; }); } }; /** * Dequeues the next message from the mailbox that is * matched by given behavior. */ template void receive(Ts&&... xs) { static_assert(sizeof...(Ts), "at least one argument required"); behavior bhvr{std::forward(xs)...}; dequeue(bhvr); } /** * Semantically equal to: `for (;;) { receive(...); }`, but does * not cause a temporary behavior object per iteration. */ template void receive_loop(Ts&&... xs) { behavior bhvr{std::forward(xs)...}; for (;;) dequeue(bhvr); } /** * Receives messages for range `[begin, first)`. * Semantically equal to: * `for ( ; begin != end; ++begin) { receive(...); }`. * * **Usage example:** * ~~~ * int i = 0; * receive_for(i, 10) ( * on(atom("get")) >> [&]() -> message { * return {"result", i}; * } * ); * ~~~ */ template receive_for_helper receive_for(T& begin, const T& end) { return {make_dequeue_callback(), begin, end}; } /** * Receives messages as long as `stmt` returns true. * Semantically equal to: `while (stmt()) { receive(...); }`. * * **Usage example:** * ~~~ * int i = 0; * receive_while([&]() { return (++i <= 10); }) * ( * on() >> int_fun, * on() >> float_fun * ); * ~~~ */ template receive_while_helper receive_while(Statement stmt) { static_assert(std::is_same::value, "functor or function does not return a boolean"); return {make_dequeue_callback(), stmt}; } /** * Receives messages until `stmt` returns true. * * Semantically equal to: * `do { receive(...); } while (stmt() == false);` * * **Usage example:** * ~~~ * int i = 0; * do_receive * ( * on() >> int_fun, * on() >> float_fun * ) * .until([&]() { return (++i >= 10); }; * ~~~ */ template do_receive_helper do_receive(Ts&&... xs) { return {make_dequeue_callback(), behavior{std::forward(xs)...}}; } /** * Blocks this actor until all other actors are done. */ void await_all_other_actors_done(); /** * Implements the actor's behavior. */ virtual void act() = 0; /** @cond PRIVATE */ void initialize() override; void dequeue(behavior& bhvr, message_id mid = invalid_message_id); /** @endcond */ protected: // helper function to implement receive_(for|while) and do_receive std::function make_dequeue_callback() { return [=](behavior& bhvr) { dequeue(bhvr); }; } }; class blocking_actor::functor_based : public blocking_actor { public: using act_fun = std::function; template functor_based(F f, Ts&&... xs) { using trait = typename detail::get_callable_trait::type; using arg0 = typename detail::tl_head::type; blocking_actor* dummy = nullptr; std::integral_constant::value> tk; create(dummy, tk, f, std::forward(xs)...); } void cleanup(uint32_t reason); protected: void act() override; private: void create(blocking_actor*, act_fun); template void create(Actor* dummy, std::true_type, F f, Ts&&... xs) { create(dummy, std::bind(f, std::placeholders::_1, std::forward(xs)...)); } template void create(Actor* dummy, std::false_type, F f, Ts&&... xs) { std::function fun = std::bind(f, std::forward(xs)...); create(dummy, [fun](Actor*) { fun(); }); } act_fun m_act; }; } // namespace caf #endif // CAF_BLOCKING_ACTOR_HPP actor-framework-0.13.2/libcaf_core/caf/channel.hpp000066400000000000000000000061531251275671500220220ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_CHANNEL_HPP #define CAF_CHANNEL_HPP #include #include #include "caf/intrusive_ptr.hpp" #include "caf/fwd.hpp" #include "caf/abstract_channel.hpp" #include "caf/detail/comparable.hpp" namespace caf { class actor; class group; class execution_unit; struct invalid_actor_t; struct invalid_group_t; /** * A handle to instances of `abstract_channel`. */ class channel : detail::comparable, detail::comparable, detail::comparable { public: template friend T actor_cast(const U&); channel() = default; channel(const actor&); channel(const group&); channel(const invalid_actor_t&); channel(const invalid_group_t&); template channel(intrusive_ptr ptr, typename std::enable_if< std::is_base_of::value >::type* = 0) : m_ptr(ptr) { // nop } channel(abstract_channel* ptr); inline explicit operator bool() const { return static_cast(m_ptr); } inline bool operator!() const { return !m_ptr; } inline abstract_channel* operator->() const { return m_ptr.get(); } inline abstract_channel& operator*() const { return *m_ptr; } intptr_t compare(const channel& other) const; intptr_t compare(const actor& other) const; intptr_t compare(const abstract_channel* other) const; static intptr_t compare(const abstract_channel* lhs, const abstract_channel* rhs); private: inline abstract_channel* get() const { return m_ptr.get(); } abstract_channel_ptr m_ptr; }; } // namespace caf #endif // CAF_CHANNEL_HPP actor-framework-0.13.2/libcaf_core/caf/check_typed_input.hpp000066400000000000000000000047061251275671500241150ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_CHECK_TYPED_INPUT_HPP #define CAF_CHECK_TYPED_INPUT_HPP #include "caf/typed_actor.hpp" #include "caf/detail/type_list.hpp" #include "caf/detail/typed_actor_util.hpp" namespace caf { /** * Checks whether `R` does support an input of type `{Ts...}` via a * static assertion (always returns 0). */ template void check_typed_input(const typed_actor&, const detail::type_list&) { static_assert(detail::tl_find< detail::type_list, atom_value >::value == -1, "atom(...) notation is not sufficient for static type " "checking, please use atom_constant instead in this context"); static_assert(detail::tl_find_if< detail::type_list, detail::input_is>::template eval >::value >= 0, "typed actor does not support given input"); } } // namespace caf #endif // CAF_CHECK_TYPED_INPUT_HPP actor-framework-0.13.2/libcaf_core/caf/config.hpp000066400000000000000000000210471251275671500216560ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_CONFIG_HPP #define CAF_CONFIG_HPP // Config pararameters defined by the build system (usually CMake): // // CAF_ENABLE_RUNTIME_CHECKS: // - check requirements at runtime // // CAF_LOG_LEVEL: // - denotes the amount of logging, ranging from error messages only (0) // to complete traces (4) /** * Denotes version of CAF in the format {MAJOR}{MINOR}{PATCH}, * whereas each number is a two-digit decimal number without * leading zeros (e.g. 900 is version 0.9.0). */ #define CAF_VERSION 1302 /** * Defined to the major version number of CAF. **/ #define CAF_MAJOR_VERSION (CAF_VERSION / 10000) /** * Defined to the minor version number of CAF. **/ #define CAF_MINOR_VERSION ((CAF_VERSION / 100) % 100) /** * Defined to the patch version number of CAF. **/ #define CAF_PATCH_VERSION (CAF_VERSION % 100) // This compiler-specific block defines: // - CAF_DEPRECATED to annotate deprecated functions // - CAF_PUSH_WARNINGS/CAF_POP_WARNINGS to surround "noisy" header includes // - CAF_ANNOTATE_FALLTHROUGH to suppress warnings in switch/case statements // - CAF_COMPILER_VERSION to retrieve the compiler version in CAF_VERSION format // - One of the following: // + CAF_CLANG // + CAF_GCC // + CAF_MSVC // sets CAF_DEPRECATED, CAF_ANNOTATE_FALLTHROUGH, // CAF_PUSH_WARNINGS and CAF_POP_WARNINGS #if defined(__clang__) # define CAF_CLANG # define CAF_DEPRECATED __attribute__((__deprecated__)) # define CAF_PUSH_WARNINGS \ _Pragma("clang diagnostic push") \ _Pragma("clang diagnostic ignored \"-Wall\"") \ _Pragma("clang diagnostic ignored \"-Wextra\"") \ _Pragma("clang diagnostic ignored \"-Werror\"") \ _Pragma("clang diagnostic ignored \"-Wdeprecated\"") \ _Pragma("clang diagnostic ignored \"-Wdisabled-macro-expansion\"") \ _Pragma("clang diagnostic ignored \"-Wextra-semi\"") \ _Pragma("clang diagnostic ignored \"-Wdocumentation\"") \ _Pragma("clang diagnostic ignored \"-Wweak-vtables\"") \ _Pragma("clang diagnostic ignored \"-Wunused-parameter\"") \ _Pragma("clang diagnostic ignored \"-Wswitch-enum\"") \ _Pragma("clang diagnostic ignored \"-Wshadow\"") \ _Pragma("clang diagnostic ignored \"-Wconversion\"") \ _Pragma("clang diagnostic ignored \"-Wcast-align\"") \ _Pragma("clang diagnostic ignored \"-Wundef\"") \ _Pragma("clang diagnostic ignored \"-Wnested-anon-types\"") \ _Pragma("clang diagnostic ignored \"-Wdeprecated\"") \ _Pragma("clang diagnostic ignored \"-Wdisabled-macro-expansion\"") \ _Pragma("clang diagnostic ignored \"-Wdocumentation\"") \ _Pragma("clang diagnostic ignored \"-Wfloat-equal\"") \ _Pragma("clang diagnostic ignored \"-Wimplicit-fallthrough\"") \ _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \ _Pragma("clang diagnostic ignored \"-Wshadow\"") \ _Pragma("clang diagnostic ignored \"-Wshorten-64-to-32\"") \ _Pragma("clang diagnostic ignored \"-Wsign-conversion\"") \ _Pragma("clang diagnostic ignored \"-Wundef\"") \ _Pragma("clang diagnostic ignored \"-Wweak-vtables\"") \ _Pragma("clang diagnostic ignored \"-Wused-but-marked-unused\"") \ _Pragma("clang diagnostic ignored \"-Wdisabled-macro-expansion\"") \ _Pragma("clang diagnostic ignored \"-Wsign-conversion\"") # define CAF_POP_WARNINGS \ _Pragma("clang diagnostic pop") # define CAF_ANNOTATE_FALLTHROUGH [[clang::fallthrough]] # define CAF_COMPILER_VERSION \ (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) #elif defined(__GNUC__) # define CAF_GCC # define CAF_DEPRECATED __attribute__((__deprecated__)) # define CAF_PUSH_WARNINGS # define CAF_POP_WARNINGS # define CAF_ANNOTATE_FALLTHROUGH static_cast(0) # define CAF_COMPILER_VERSION \ (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) #elif defined(_MSC_VER) # define CAF_MSVC # define CAF_DEPRECATED # define CAF_PUSH_WARNINGS # define CAF_POP_WARNINGS # define CAF_ANNOTATE_FALLTHROUGH static_cast(0) # define CAF_COMPILER_VERSION _MSC_FULL_VER #else # define CAF_DEPRECATED # define CAF_PUSH_WARNINGS # define CAF_POP_WARNINGS # define CAF_ANNOTATE_FALLTHROUGH static_cast(0) #endif // This OS-specific block defines one of the following: // - CAF_MACOS // - CAF_LINUX // - CAF_BSD // - CAF_WINDOWS // It also defines CAF_POSIX for POSIX-compatible systems #if defined(__APPLE__) # include "TargetConditionals.h" # if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR # define CAF_IOS # else # define CAF_MACOS # ifndef _GLIBCXX_HAS_GTHREADS # define _GLIBCXX_HAS_GTHREADS # endif # endif #elif defined(__ANDROID__) # define CAF_ANDROID #elif defined(__linux__) # define CAF_LINUX # include # if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,16) # define CAF_POLL_IMPL # endif #elif defined(__FreeBSD__) # define CAF_BSD #elif defined(WIN32) || defined(_WIN32) # define CAF_WINDOWS #else # error Platform and/or compiler not supportet #endif #if defined(CAF_MACOS) || defined(CAF_LINUX) || defined(CAF_BSD) # define CAF_POSIX #endif #include #include // Optionally enable CAF_ASSERT #ifndef CAF_ENABLE_RUNTIME_CHECKS # define CAF_ASSERT(unused) static_cast(0) #elif defined(CAF_WINDOWS) || defined(CAF_BSD) # define CAF_ASSERT(stmt) \ if (static_cast(stmt) == false) { \ printf("%s:%u: requirement failed '%s'\n", __FILE__, __LINE__, #stmt); \ abort(); \ } static_cast(0) #else // defined(CAF_LINUX) || defined(CAF_MACOS) # include # define CAF_ASSERT(stmt) \ if (static_cast(stmt) == false) { \ printf("%s:%u: requirement failed '%s'\n", __FILE__, __LINE__, #stmt); \ void* array[10]; \ auto caf_bt_size = ::backtrace(array, 10); \ ::backtrace_symbols_fd(array, caf_bt_size, 2); \ abort(); \ } static_cast(0) #endif #define CAF_CRITICAL(error) \ printf("%s:%u: critical error: '%s'\n", __FILE__, __LINE__, error); \ abort() #endif // CAF_CONFIG_HPP actor-framework-0.13.2/libcaf_core/caf/continue_helper.hpp000066400000000000000000000040571251275671500235760ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CONTINUE_HELPER_HPP #define CONTINUE_HELPER_HPP #include #include "caf/on.hpp" #include "caf/behavior.hpp" #include "caf/message_id.hpp" #include "caf/message_handler.hpp" namespace caf { class local_actor; /** * Helper class to enable users to add continuations * when dealing with synchronous sends. */ class continue_helper { public: using message_id_wrapper_tag = int; continue_helper(message_id mid); /** * Returns the ID of the expected response message. */ message_id get_message_id() const { return m_mid; } private: message_id m_mid; }; } // namespace caf #endif // CONTINUE_HELPER_HPP actor-framework-0.13.2/libcaf_core/caf/default_attachable.hpp000066400000000000000000000054101251275671500242010ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_DEFAULT_ATTACHABLE_HPP #define CAF_DEFAULT_ATTACHABLE_HPP #include "caf/actor_addr.hpp" #include "caf/attachable.hpp" namespace caf { class default_attachable : public attachable { public: enum observe_type { monitor, link }; struct observe_token { actor_addr observer; observe_type type; static constexpr size_t token_type = attachable::token::observer; }; void actor_exited(abstract_actor* self, uint32_t reason) override; bool matches(const token& what) override; inline static attachable_ptr make_monitor(actor_addr observer) { return attachable_ptr{new default_attachable(std::move(observer), monitor)}; } inline static attachable_ptr make_link(actor_addr observer) { return attachable_ptr{new default_attachable(std::move(observer), link)}; } class predicate { public: inline predicate(actor_addr observer, observe_type type) : m_observer(std::move(observer)), m_type(type) { // nop } inline bool operator()(const attachable_ptr& ptr) const { return ptr->matches(observe_token{m_observer, m_type}); } private: actor_addr m_observer; observe_type m_type; }; private: default_attachable(actor_addr observer, observe_type type); actor_addr m_observer; observe_type m_type; }; } // namespace caf #endif // CAF_DEFAULT_ATTACHABLE_HPP actor-framework-0.13.2/libcaf_core/caf/deserializer.hpp000066400000000000000000000071251251275671500230740ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_DESERIALIZER_HPP #define CAF_DESERIALIZER_HPP #include #include #include "caf/primitive_variant.hpp" #include "caf/uniform_type_info.hpp" namespace caf { class actor_namespace; class uniform_type_info; /** * @ingroup TypeSystem * Technology-independent deserialization interface. */ class deserializer { deserializer(const deserializer&) = delete; deserializer& operator=(const deserializer&) = delete; public: deserializer(actor_namespace* ns = nullptr); virtual ~deserializer(); /** * Begins deserialization of a new object. */ virtual const uniform_type_info* begin_object() = 0; /** * Ends deserialization of an object. */ virtual void end_object() = 0; /** * Begins deserialization of a sequence. * @returns The size of the sequence. */ virtual size_t begin_sequence() = 0; /** * Ends deserialization of a sequence. */ virtual void end_sequence() = 0; /** * Reads a primitive value from the data source. */ virtual void read_value(primitive_variant& storage) = 0; /** * Reads a value of type `T` from the data source. * @note `T` must be a primitive type. */ template inline T read() { primitive_variant val{T()}; read_value(val); return std::move(get(val)); } template inline T read(const uniform_type_info* uti) { T result; uti->deserialize(&result, this); return result; } template inline deserializer& read(T& storage) { primitive_variant val{T()}; read_value(val); storage = std::move(get(val)); return *this; } template inline deserializer& read(T& storage, const uniform_type_info* uti) { uti->deserialize(&storage, this); return *this; } /** * Reads a raw memory block. */ virtual void read_raw(size_t num_bytes, void* storage) = 0; inline actor_namespace* get_namespace() { return m_namespace; } template void read_raw(size_t num_bytes, Buffer& storage) { storage.resize(num_bytes); read_raw(num_bytes, storage.data()); } private: actor_namespace* m_namespace; }; } // namespace caf #endif // CAF_DESERIALIZER_HPP actor-framework-0.13.2/libcaf_core/caf/detail/000077500000000000000000000000001251275671500211365ustar00rootroot00000000000000actor-framework-0.13.2/libcaf_core/caf/detail/abstract_uniform_type_info.hpp000066400000000000000000000072501251275671500272710ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_DETAIL_ABSTRACT_UNIFORM_TYPE_INFO_HPP #define CAF_DETAIL_ABSTRACT_UNIFORM_TYPE_INFO_HPP #include "caf/message.hpp" #include "caf/deserializer.hpp" #include "caf/uniform_type_info.hpp" #include "caf/detail/type_traits.hpp" #include "caf/detail/uniform_type_info_map.hpp" namespace caf { namespace detail { /** * Implements all pure virtual functions of `uniform_type_info` * except serialize() and deserialize(). */ template class abstract_uniform_type_info : public uniform_type_info { public: const char* name() const override { return m_name.c_str(); } message as_message(void* instance) const override { return make_message(deref(instance)); } bool equal_to(const std::type_info& tinfo) const override { return m_native == &tinfo || *m_native == tinfo; } bool equals(const void* lhs, const void* rhs) const override { return eq(deref(lhs), deref(rhs)); } uniform_value create(const uniform_value& other) const override { return create_impl(other); } protected: abstract_uniform_type_info(std::string tname) : m_name(std::move(tname)), m_native(&typeid(T)) { // nop } static const T& deref(const void* ptr) { return *reinterpret_cast(ptr); } static T& deref(void* ptr) { return *reinterpret_cast(ptr); } // can be overridden in subclasses to compare POD types // by comparing each individual member virtual bool pod_mems_equals(const T&, const T&) const { return false; } std::string m_name; const std::type_info* m_native; private: template typename std::enable_if::value, bool>::type eq(const C&, const C&) const { return true; } template typename std::enable_if::value && detail::is_comparable::value, bool>::type eq(const C& lhs, const C& rhs) const { return lhs == rhs; } template typename std::enable_if::value && std::is_pod::value && !detail::is_comparable::value, bool>::type eq(const C& lhs, const C& rhs) const { return pod_mems_equals(lhs, rhs); } }; } // namespace detail } // namespace caf #endif // CAF_DETAIL_ABSTRACT_UNIFORM_TYPE_INFO_HPP actor-framework-0.13.2/libcaf_core/caf/detail/actor_registry.hpp000066400000000000000000000062241251275671500247130ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_DETAIL_ACTOR_REGISTRY_HPP #define CAF_DETAIL_ACTOR_REGISTRY_HPP #include #include #include #include #include #include #include "caf/abstract_actor.hpp" #include "caf/detail/shared_spinlock.hpp" #include "caf/detail/singleton_mixin.hpp" namespace caf { namespace detail { class singletons; class actor_registry : public singleton_mixin { public: friend class singleton_mixin; ~actor_registry(); /** * A registry entry consists of a pointer to the actor and an * exit reason. An entry with a nullptr means the actor has finished * execution for given reason. */ using value_type = std::pair; value_type get_entry(actor_id key) const; // return nullptr if the actor wasn't put *or* finished execution inline abstract_actor_ptr get(actor_id key) const { return get_entry(key).first; } void put(actor_id key, const abstract_actor_ptr& value); void erase(actor_id key, uint32_t reason); // gets the next free actor id actor_id next_id(); // increases running-actors-count by one void inc_running(); // decreases running-actors-count by one void dec_running(); size_t running() const; // blocks the caller until running-actors-count becomes `expected` void await_running_count_equal(size_t expected); private: using entries = std::map; actor_registry(); std::atomic m_running; std::atomic m_ids; std::mutex m_running_mtx; std::condition_variable m_running_cv; mutable detail::shared_spinlock m_instances_mtx; entries m_entries; }; } // namespace detail } // namespace caf #endif // CAF_DETAIL_ACTOR_REGISTRY_HPP actor-framework-0.13.2/libcaf_core/caf/detail/apply_args.hpp000066400000000000000000000055141251275671500240150ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_DETAIL_APPLY_ARGS_HPP #define CAF_DETAIL_APPLY_ARGS_HPP #include #include "caf/detail/int_list.hpp" #include "caf/detail/type_list.hpp" namespace caf { namespace detail { // this utterly useless function works around a bug in Clang that causes // the compiler to reject the trailing return type of apply_args because // "get" is not defined (it's found during ADL) template typename tl_at, Pos>::type get(const type_list&); template auto apply_args(F& f, detail::int_list, Tuple&& tup) -> decltype(f(get(tup)...)) { return f(get(tup)...); } template auto apply_args_prefixed(F& f, detail::int_list<>, Tuple&, Ts&&... xs) -> decltype(f(std::forward(xs)...)) { return f(std::forward(xs)...); } template auto apply_args_prefixed(F& f, detail::int_list, Tuple& tup, Ts&&... xs) -> decltype(f(std::forward(xs)..., get(tup)...)) { return f(std::forward(xs)..., get(tup)...); } template auto apply_args_suffxied(F& f, detail::int_list, Tuple& tup, Ts&&... xs) -> decltype(f(get(tup)..., std::forward(xs)...)) { return f(get(tup)..., std::forward(xs)...); } } // namespace detail } // namespace caf #endif // CAF_DETAIL_APPLY_ARGS_HPP actor-framework-0.13.2/libcaf_core/caf/detail/arg_match_t.hpp000066400000000000000000000031641251275671500241230ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_DETAIL_ARG_MATCH_T_HPP #define CAF_DETAIL_ARG_MATCH_T_HPP namespace caf { namespace detail { struct arg_match_t {}; } // namespace detail } // namespace caf #endif // CAF_DETAIL_ARG_MATCH_T_HPP actor-framework-0.13.2/libcaf_core/caf/detail/atom_val.hpp000066400000000000000000000056231251275671500234570ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_DETAIL_ATOM_VAL_HPP #define CAF_DETAIL_ATOM_VAL_HPP namespace caf { namespace detail { namespace { // encodes ASCII characters to 6bit encoding constexpr unsigned char encoding_table[] = { /* ..0 ..1 ..2 ..3 ..4 ..5 ..6 ..7 ..8 ..9 ..A ..B ..C ..D ..E ..F */ /* 0.. */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1.. */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2.. */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 3.. */ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, 0, 0, 0, 0, /* 4.. */ 0, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, /* 5.. */ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 0, 0, 0, 0, 37, /* 6.. */ 0, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, /* 7.. */ 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 0, 0, 0, 0, 0}; // decodes 6bit characters to ASCII constexpr char decoding_table[] = " 0123456789" "ABCDEFGHIJKLMNOPQRSTUVWXYZ_" "abcdefghijklmnopqrstuvwxyz"; } // namespace constexpr uint64_t next_interim(uint64_t current, size_t char_code) { return (current << 6) | encoding_table[(char_code <= 0x7F) ? char_code : 0]; } constexpr uint64_t atom_val(const char* cstr, uint64_t interim = 0) { return (*cstr == '\0') ? interim : atom_val(cstr + 1, next_interim(interim, static_cast(*cstr))); } } // namespace detail } // namespace caf #endif // CAF_DETAIL_ATOM_VAL_HPP actor-framework-0.13.2/libcaf_core/caf/detail/behavior_impl.hpp000066400000000000000000000162601251275671500244740ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_DETAIL_BEHAVIOR_IMPL_HPP #define CAF_DETAIL_BEHAVIOR_IMPL_HPP #include #include #include "caf/none.hpp" #include "caf/variant.hpp" #include "caf/optional.hpp" #include "caf/match_case.hpp" #include "caf/make_counted.hpp" #include "caf/intrusive_ptr.hpp" #include "caf/atom.hpp" #include "caf/either.hpp" #include "caf/message.hpp" #include "caf/duration.hpp" #include "caf/ref_counted.hpp" #include "caf/skip_message.hpp" #include "caf/response_promise.hpp" #include "caf/timeout_definition.hpp" #include "caf/typed_response_promise.hpp" #include "caf/detail/int_list.hpp" #include "caf/detail/apply_args.hpp" #include "caf/detail/type_traits.hpp" #include "caf/detail/tail_argument_token.hpp" #include "caf/detail/optional_message_visitor.hpp" namespace caf { class message_handler; using bhvr_invoke_result = optional; } // namespace caf namespace caf { namespace detail { template struct has_skip_message { static constexpr bool value = disjunction::value...>::value; }; class behavior_impl : public ref_counted { public: using pointer = intrusive_ptr; ~behavior_impl(); behavior_impl(duration tout = duration{}); virtual bhvr_invoke_result invoke(message&); inline bhvr_invoke_result invoke(message&& arg) { message tmp(std::move(arg)); return invoke(tmp); } virtual void handle_timeout(); inline const duration& timeout() const { return m_timeout; } virtual pointer copy(const generic_timeout_definition& tdef) const = 0; pointer or_else(const pointer& other); protected: duration m_timeout; match_case_info* m_begin; match_case_info* m_end; }; template struct defaut_bhvr_impl_init { template static void init(Array& arr, Tuple& tup) { auto& x = arr[Pos]; x.ptr = &std::get(tup); x.has_wildcard = x.ptr->has_wildcard(); x.type_token = x.ptr->type_token(); defaut_bhvr_impl_init::init(arr, tup); } }; template struct defaut_bhvr_impl_init { template static void init(Array&, Tuple&) { // nop } }; template class default_behavior_impl : public behavior_impl { public: static constexpr size_t num_cases = std::tuple_size::value; default_behavior_impl(Tuple tup) : m_cases(std::move(tup)) { init(); } template default_behavior_impl(Tuple tup, timeout_definition d) : behavior_impl(d.timeout), m_cases(std::move(tup)), m_fun(d.handler) { init(); } typename behavior_impl::pointer copy(const generic_timeout_definition& tdef) const override { return make_counted>(m_cases, tdef); } void handle_timeout() override { m_fun(); } private: void init() { defaut_bhvr_impl_init<0, num_cases>::init(m_arr, m_cases); m_begin = m_arr.data(); m_end = m_begin + m_arr.size(); } Tuple m_cases; std::array m_arr; std::function m_fun; }; // eor = end of recursion // ra = reorganize arguments template intrusive_ptr make_behavior_eor(std::tuple match_cases) { return make_counted(std::move(match_cases)); } template intrusive_ptr make_behavior_eor(std::tuple match_cases, timeout_definition& td) { return make_counted(std::move(match_cases), std::move(td)); } template ::value> struct lift_to_mctuple { using type = std::tuple>; }; template struct lift_to_mctuple { using type = std::tuple; }; template struct lift_to_mctuple, false> { using type = std::tuple; }; template struct lift_to_mctuple, false> { using type = std::tuple<>; }; template struct join_std_tuples; template struct join_std_tuples { using type = T; }; template struct join_std_tuples, std::tuple, Suffix...> : join_std_tuples, Suffix...> { // nop }; // this function reorganizes its arguments to shift the timeout definition // to the front (receives it at the tail) template intrusive_ptr make_behavior_ra(timeout_definition& td, tail_argument_token&, Ts... xs) { return make_behavior_eor(std::tuple_cat(to_match_case_tuple(xs)...), td); } template intrusive_ptr make_behavior_ra(tail_argument_token&, Ts... xs) { return make_behavior_eor(std::tuple_cat(to_match_case_tuple(xs)...)); } // for some reason, this call is ambigious on GCC without enable_if template typename std::enable_if< !std::is_same::value, intrusive_ptr >::type make_behavior_ra(V& v, Ts&... xs) { return make_behavior_ra(xs..., v); } // this function reorganizes its arguments to shift the timeout definition // to the front (receives it at the tail) template intrusive_ptr< default_behavior_impl< typename join_std_tuples< typename lift_to_mctuple::type... >::type >> make_behavior(Ts&... xs) { using result_type = default_behavior_impl< typename join_std_tuples< typename lift_to_mctuple::type... >::type >; tail_argument_token eoa; return make_behavior_ra(xs..., eoa); } using behavior_impl_ptr = intrusive_ptr; } // namespace detail } // namespace caf #endif // CAF_DETAIL_BEHAVIOR_IMPL_HPP actor-framework-0.13.2/libcaf_core/caf/detail/behavior_stack.hpp000066400000000000000000000050411251275671500246330ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_DETAIL_BEHAVIOR_STACK_HPP #define CAF_DETAIL_BEHAVIOR_STACK_HPP #include #include #include #include #include "caf/optional.hpp" #include "caf/config.hpp" #include "caf/behavior.hpp" #include "caf/message_id.hpp" #include "caf/mailbox_element.hpp" namespace caf { namespace detail { struct behavior_stack_mover; class behavior_stack { public: friend struct behavior_stack_mover; behavior_stack(const behavior_stack&) = delete; behavior_stack& operator=(const behavior_stack&) = delete; behavior_stack() = default; // erases the last (asynchronous) behavior void pop_back(); void clear(); inline bool empty() const { return m_elements.empty(); } inline behavior& back() { CAF_ASSERT(!empty()); return m_elements.back(); } inline void push_back(behavior&& what) { m_elements.emplace_back(std::move(what)); } inline void cleanup() { m_erased_elements.clear(); } private: std::vector m_elements; std::vector m_erased_elements; }; } // namespace detail } // namespace caf #endif // CAF_DETAIL_BEHAVIOR_STACK_HPP actor-framework-0.13.2/libcaf_core/caf/detail/boxed.hpp000066400000000000000000000045411251275671500227540ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_DETAIL_BOXED_HPP #define CAF_DETAIL_BOXED_HPP #include "caf/anything.hpp" #include "caf/detail/wrapped.hpp" namespace caf { namespace detail { template struct boxed { using type = detail::wrapped; }; template struct boxed> { using type = detail::wrapped; }; template <> struct boxed { using type = anything; }; template struct is_boxed { static constexpr bool value = false; }; template struct is_boxed> { static constexpr bool value = true; }; template struct is_boxed()> { static constexpr bool value = true; }; template struct is_boxed(&)()> { static constexpr bool value = true; }; template struct is_boxed(*)()> { static constexpr bool value = true; }; } // namespace detail } // namespace caf #endif // CAF_DETAIL_BOXED_HPP actor-framework-0.13.2/libcaf_core/caf/detail/cas_weak.hpp000066400000000000000000000037701251275671500234330ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_DETAIL_CAS_WEAK_HPP #define CAF_DETAIL_CAS_WEAK_HPP #include #include "caf/config.hpp" namespace caf { namespace detail { template bool cas_weak(std::atomic* obj, T* expected, T desired) { # if (defined(CAF_CLANG) && CAF_COMPILER_VERSION < 30401) \ || (defined(CAF_GCC) && CAF_COMPILER_VERSION < 40803) return std::atomic_compare_exchange_strong(obj, expected, desired); # else return std::atomic_compare_exchange_weak(obj, expected, desired); # endif } } // namespace detail } // namespace caf #endif // CAF_DETAIL_CAS_WEAK_HPP actor-framework-0.13.2/libcaf_core/caf/detail/comparable.hpp000066400000000000000000000073521251275671500237630ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_COMPARABLE_HPP #define CAF_COMPARABLE_HPP namespace caf { namespace detail { /** * Barton–Nackman trick implementation. * `Subclass` must provide a compare member function that compares * to instances of `T` and returns an integer x with: * - `x < 0` if `*this < other` * - `x > 0` if `*this > other` * - `x == 0` if `*this == other` */ template class comparable { friend bool operator==(const Subclass& lhs, const T& rhs) { return lhs.compare(rhs) == 0; } friend bool operator==(const T& lhs, const Subclass& rhs) { return rhs.compare(lhs) == 0; } friend bool operator!=(const Subclass& lhs, const T& rhs) { return lhs.compare(rhs) != 0; } friend bool operator!=(const T& lhs, const Subclass& rhs) { return rhs.compare(lhs) != 0; } friend bool operator<(const Subclass& lhs, const T& rhs) { return lhs.compare(rhs) < 0; } friend bool operator>(const Subclass& lhs, const T& rhs) { return lhs.compare(rhs) > 0; } friend bool operator<(const T& lhs, const Subclass& rhs) { return rhs > lhs; } friend bool operator>(const T& lhs, const Subclass& rhs) { return rhs < lhs; } friend bool operator<=(const Subclass& lhs, const T& rhs) { return lhs.compare(rhs) <= 0; } friend bool operator>=(const Subclass& lhs, const T& rhs) { return lhs.compare(rhs) >= 0; } friend bool operator<=(const T& lhs, const Subclass& rhs) { return rhs >= lhs; } friend bool operator>=(const T& lhs, const Subclass& rhs) { return rhs <= lhs; } }; template class comparable { friend bool operator==(const Subclass& lhs, const Subclass& rhs) { return lhs.compare(rhs) == 0; } friend bool operator!=(const Subclass& lhs, const Subclass& rhs) { return lhs.compare(rhs) != 0; } friend bool operator<(const Subclass& lhs, const Subclass& rhs) { return lhs.compare(rhs) < 0; } friend bool operator<=(const Subclass& lhs, const Subclass& rhs) { return lhs.compare(rhs) <= 0; } friend bool operator>(const Subclass& lhs, const Subclass& rhs) { return lhs.compare(rhs) > 0; } friend bool operator>=(const Subclass& lhs, const Subclass& rhs) { return lhs.compare(rhs) >= 0; } }; } // namespace details } // namespace caf #endif // CAF_COMPARABLE_HPP actor-framework-0.13.2/libcaf_core/caf/detail/concatenated_tuple.hpp000066400000000000000000000051551251275671500255160ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_DETAIL_CONCATENATED_TUPLE_HPP #define CAF_DETAIL_CONCATENATED_TUPLE_HPP #include #include #include "caf/detail/decorated_tuple.hpp" namespace caf { namespace detail { class concatenated_tuple : public message_data { public: concatenated_tuple& operator=(const concatenated_tuple&) = delete; using message_data::cow_ptr; using vector_type = std::vector; static cow_ptr make(std::initializer_list xs); void* mutable_at(size_t pos) override; size_t size() const override; cow_ptr copy() const override; const void* at(size_t pos) const override; bool match_element(size_t pos, uint16_t typenr, const std::type_info* rtti) const override; uint32_t type_token() const override; const char* uniform_name_at(size_t pos) const override; uint16_t type_nr_at(size_t pos) const override; concatenated_tuple() = default; private: concatenated_tuple(const concatenated_tuple&) = default; std::pair select(size_t pos) const; void init(); vector_type m_data; uint32_t m_type_token; size_t m_size; }; } // namespace detail } // namespace caf #endif // CAF_DETAIL_CONCATENATED_TUPLE_HPP actor-framework-0.13.2/libcaf_core/caf/detail/ctm.hpp000066400000000000000000000116341251275671500224370ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_DETAIL_CTM_HPP #define CAF_DETAIL_CTM_HPP #include "caf/replies_to.hpp" #include "caf/typed_response_promise.hpp" #include "caf/detail/type_list.hpp" #include "caf/detail/typed_actor_util.hpp" namespace caf { namespace detail { // CTM: Compile-Time Match // left hand side is the MPI we are comparing to, this is *not* commutative template struct ctm_cmp : std::false_type { }; template struct ctm_cmp, typed_mpi> { static constexpr bool value = std::is_same::value || std::is_same::value; }; /* template struct ctm_cmp, typed_mpi> : std::true_type { }; template struct ctm_cmp, typed_mpi> : std::true_type { }; */ template struct ctm_cmp, typed_mpi>, empty_type_list>> : std::true_type { }; template struct ctm_cmp, typed_mpi>, empty_type_list>> : std::true_type { }; template struct ctm_cmp, typed_mpi, empty_type_list>> : std::true_type { }; template struct ctm_cmp, typed_mpi>>, empty_type_list>> : std::true_type { }; /* template struct ctm_cmp, typed_mpi> : std::true_type { }; */ template struct ctm_cmp, typed_mpi> : std::true_type { }; template struct ctm_impl { // : std::integral_constant { // -2 means: to few message handlers defined static constexpr int value = (tl_size::value < tl_size::value) ? -2 : -3; }; template struct ctm_impl : std::integral_constant { // everything's fine, -1 means: no mismatch found (both sets are empty) }; template struct ctm_impl, type_list, Pos> { using next_ys = typename tl_filter_not< type_list, tbind::template type >::type; static constexpr int value = // check if filter_not did remove something sizeof...(Ys) == tl_size::value ? Pos // error at this position : ctm_impl, next_ys, Pos + 1>::value; }; template struct ctm { // -3 means too many handler, -2 means too few, -1 means OK, everything else // mismatch at that position static constexpr size_t num_xs = tl_size::value; static constexpr size_t num_ys = tl_size::value; /* static constexpr int value = num_xs != num_ys ? num_xs > num_ys ? -3 : -2 : ctm_impl::value; */ static constexpr int value = ctm_impl::value; }; } // namespace detail } // namespace caf #endif // CAF_DETAIL_CTM_HPP actor-framework-0.13.2/libcaf_core/caf/detail/decorated_tuple.hpp000066400000000000000000000056011251275671500250140ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_DETAIL_DECORATED_TUPLE_HPP #define CAF_DETAIL_DECORATED_TUPLE_HPP #include #include #include "caf/config.hpp" #include "caf/ref_counted.hpp" #include "caf/uniform_type_info.hpp" #include "caf/detail/type_list.hpp" #include "caf/detail/tuple_vals.hpp" #include "caf/detail/message_data.hpp" namespace caf { namespace detail { class decorated_tuple : public message_data { public: decorated_tuple& operator=(const decorated_tuple&) = delete; using vector_type = std::vector; using message_data::cow_ptr; decorated_tuple(cow_ptr&&, vector_type&&); // creates a typed subtuple from `d` with mapping `v` static cow_ptr make(cow_ptr d, vector_type v); void* mutable_at(size_t pos) override; size_t size() const override; cow_ptr copy() const override; const void* at(size_t pos) const override; bool match_element(size_t pos, uint16_t typenr, const std::type_info* rtti) const override; uint32_t type_token() const override; const char* uniform_name_at(size_t pos) const override; uint16_t type_nr_at(size_t pos) const override; inline const cow_ptr& decorated() const { return m_decorated; } inline const vector_type& mapping() const { return m_mapping; } private: decorated_tuple(const decorated_tuple&) = default; cow_ptr m_decorated; vector_type m_mapping; uint32_t m_type_token; }; } // namespace detail } // namespace caf #endif // CAF_DETAIL_DECORATED_TUPLE_HPP actor-framework-0.13.2/libcaf_core/caf/detail/default_uniform_type_info.hpp000066400000000000000000000430161251275671500271120ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_DETAIL_DEFAULT_UNIFORM_TYPE_INFO_IMPL_HPP #define CAF_DETAIL_DEFAULT_UNIFORM_TYPE_INFO_IMPL_HPP #include #include "caf/unit.hpp" #include "caf/actor.hpp" #include "caf/anything.hpp" #include "caf/serializer.hpp" #include "caf/typed_actor.hpp" #include "caf/deserializer.hpp" #include "caf/detail/type_traits.hpp" #include "caf/detail/abstract_uniform_type_info.hpp" namespace caf { namespace detail { using uniform_type_info_ptr = uniform_type_info_ptr; // check if there's a 'push_back' that takes a C::value_type template char sfinae_has_push_back(T* ptr, typename T::value_type* val = nullptr, decltype(ptr->push_back(*val)) * = nullptr); long sfinae_has_push_back(void*); // SFNINAE default template struct is_stl_compliant_list { static constexpr bool value = detail::is_iterable::value && sizeof(sfinae_has_push_back(static_cast(nullptr))) == sizeof(char); }; // check if there's an 'insert' that takes a C::value_type template char sfinae_has_insert(T* ptr, typename T::value_type* val = nullptr, decltype(ptr->insert(*val)) * = nullptr); long sfinae_has_insert(void*); // SFNINAE default template struct is_stl_compliant_map { static constexpr bool value = detail::is_iterable::value && sizeof(sfinae_has_insert(static_cast(nullptr))) == sizeof(char); }; template struct is_stl_pair : std::false_type { // no members }; template struct is_stl_pair> : std::true_type { // no members }; using primitive_impl = std::integral_constant; using list_impl = std::integral_constant; using map_impl = std::integral_constant; using pair_impl = std::integral_constant; using opt_impl = std::integral_constant; using recursive_impl = std::integral_constant; template constexpr int impl_id() { return detail::is_primitive::value ? 0 : (is_stl_compliant_list::value ? 1 : (is_stl_compliant_map::value ? 2 : (is_stl_pair::value ? 3 : (detail::is_optional::value ? 4 : 9)))); } template struct deconst_pair { using type = T; }; template struct deconst_pair> { using first_type = typename std::remove_const::type; using second_type = typename std::remove_const::type; using type = std::pair; }; class default_serialize_policy { public: template void operator()(const T& val, serializer* s) const { std::integral_constant()> token; simpl(val, s, token); } template void operator()(T& val, deserializer* d) const { std::integral_constant()> token; dimpl(val, d, token); } private: template void simpl(const T& val, serializer* s, primitive_impl) const { s->write_value(val); } template void simpl(const T& val, serializer* s, list_impl) const { s->begin_sequence(val.size()); for (auto i = val.begin(); i != val.end(); ++i) { (*this)(*i, s); } s->end_sequence(); } template void simpl(const T& val, serializer* s, map_impl) const { // lists and maps share code for serialization list_impl token; simpl(val, s, token); } template void simpl(const T& val, serializer* s, pair_impl) const { (*this)(val.first, s); (*this)(val.second, s); } template void simpl(const optional& val, serializer* s, opt_impl) const { uint8_t flag = val ? 1 : 0; s->write_value(flag); if (val) { (*this)(*val, s); } } template void simpl(const T& val, serializer* s, recursive_impl) const { uniform_typeid()->serialize(&val, s); } template void dimpl(T& storage, deserializer* d, primitive_impl) const { storage = d->read(); } template void dimpl(T& storage, deserializer* d, list_impl) const { using value_type = typename T::value_type; storage.clear(); size_t size = d->begin_sequence(); for (size_t i = 0; i < size; ++i) { value_type tmp; (*this)(tmp, d); storage.push_back(std::move(tmp)); } d->end_sequence(); } template void dimpl(T& storage, deserializer* d, map_impl) const { storage.clear(); size_t size = d->begin_sequence(); for (size_t i = 0; i < size; ++i) { typename deconst_pair::type tmp; (*this)(tmp, d); storage.insert(tmp); } d->end_sequence(); } template void dimpl(T& storage, deserializer* d, pair_impl) const { (*this)(storage.first, d); (*this)(storage.second, d); } template void dimpl(optional& val, deserializer* d, opt_impl) const { auto flag = d->read(); if (flag != 0) { T tmp; (*this)(tmp, d); val = std::move(tmp); } else { val = none; } } template void dimpl(T& storage, deserializer* d, recursive_impl) const { uniform_typeid()->deserialize(&storage, d); } }; class forwarding_serialize_policy { public: inline forwarding_serialize_policy(uniform_type_info_ptr uti) : m_uti(std::move(uti)) { // nop } template void operator()(const T& val, serializer* s) const { m_uti->serialize(&val, s); } template void operator()(T& val, deserializer* d) const { m_uti->deserialize(&val, d); } private: uniform_type_info_ptr m_uti; }; template ::value, bool IsEmptyType = std::is_class::value&& std::is_empty::value> class member_tinfo : public detail::abstract_uniform_type_info { public: using super = detail::abstract_uniform_type_info; member_tinfo(AccessPolicy apol, SerializePolicy spol) : super("--member--"), m_apol(std::move(apol)), m_spol(std::move(spol)) { // nop } member_tinfo(AccessPolicy apol) : super("--member--"), m_apol(std::move(apol)) { // nop } member_tinfo() : super("--member--") { // nop } void serialize(const void* vptr, serializer* s) const override { m_spol(m_apol(vptr), s); } void deserialize(void* vptr, deserializer* d) const override { std::integral_constant token; ds(vptr, d, token); } private: void ds(void* p, deserializer* d, std::true_type) const { m_spol(m_apol(p), d); } void ds(void* p, deserializer* d, std::false_type) const { T tmp; m_spol(tmp, d); m_apol(p, std::move(tmp)); } AccessPolicy m_apol; SerializePolicy m_spol; }; template class member_tinfo : public detail::abstract_uniform_type_info { public: using super = detail::abstract_uniform_type_info; member_tinfo(const A&, const S&) : super("--member--") { // nop } member_tinfo(const A&) : super("--member--") { // nop } member_tinfo() : super("--member--") { // nop } void serialize(const void*, serializer*) const override { // nop } void deserialize(void*, deserializer*) const override { // nop } }; template class member_tinfo : public detail::abstract_uniform_type_info { public: using super = detail::abstract_uniform_type_info; using value_type = typename std::underlying_type::type; member_tinfo(AccessPolicy apol, SerializePolicy spol) : super("--member--"), m_apol(std::move(apol)), m_spol(std::move(spol)) { // nop } member_tinfo(AccessPolicy apol) : super("--member--"), m_apol(std::move(apol)) { // nop } member_tinfo() : super("--member--") { // nop } void serialize(const void* p, serializer* s) const override { auto val = m_apol(p); m_spol(static_cast(val), s); } void deserialize(void* p, deserializer* d) const override { value_type tmp; m_spol(tmp, d); m_apol(p, static_cast(tmp)); } private: AccessPolicy m_apol; SerializePolicy m_spol; }; template class memptr_access_policy { public: inline memptr_access_policy(T C::*memptr) : m_memptr(memptr) { // nop } memptr_access_policy(const memptr_access_policy&) = default; memptr_access_policy& operator=(const memptr_access_policy&) = default; inline T& operator()(void* vptr) const { auto ptr = reinterpret_cast(vptr); return *ptr.*m_memptr; } inline const T& operator()(const void* vptr) const { auto ptr = reinterpret_cast(vptr); return *ptr.*m_memptr; } template inline void operator()(void* vptr, Arg&& value) const { auto ptr = reinterpret_cast(vptr); (*ptr.*m_memptr) = std::forward(value); } static constexpr bool grants_mutable_access = true; private: T C::*m_memptr; }; template class getter_setter_access_policy { public: using getter = GRes (C::*)() const; using setter = SRes (C::*)(SArg); getter_setter_access_policy(getter g, setter s) : m_get(g), m_set(s) {} inline GRes operator()(const void* vptr) const { auto ptr = reinterpret_cast(vptr); return (*ptr.*m_get)(); } template inline void operator()(void* vptr, Arg&& value) const { auto ptr = reinterpret_cast(vptr); (*ptr.*m_set)(std::forward(value)); } static constexpr bool grants_mutable_access = false; private: getter m_get; setter m_set; }; template struct fake_access_policy { inline T& operator()(void* vptr) const { return *reinterpret_cast(vptr); } inline const T& operator()(const void* vptr) const { return *reinterpret_cast(vptr); } template inline void operator()(void* vptr, U&& value) const { *reinterpret_cast(vptr) = std::forward(value); } static constexpr bool grants_mutable_access = true; }; template uniform_type_info_ptr new_member_tinfo(T C::*memptr) { using access_policy = memptr_access_policy; using result_type = member_tinfo; return uniform_type_info_ptr(new result_type(memptr)); } template uniform_type_info_ptr new_member_tinfo(T C::*memptr, uniform_type_info_ptr meminf) { using access_policy = memptr_access_policy; using tinfo = member_tinfo; return uniform_type_info_ptr(new tinfo(memptr, std::move(meminf))); } template uniform_type_info_ptr new_member_tinfo(GRes (C::*getter)() const, SRes (C::*setter)(SArg)) { using access_policy = getter_setter_access_policy; using value_type = typename std::decay::type; using result_type = member_tinfo; return uniform_type_info_ptr( new result_type(access_policy(getter, setter))); } template uniform_type_info_ptr new_member_tinfo(GRes (C::*getter)() const, SRes (C::*setter)(SArg), uniform_type_info_ptr meminf) { using access_policy = getter_setter_access_policy; using value_type = typename std::decay::type; using tinfo = member_tinfo; return uniform_type_info_ptr(new tinfo(access_policy(getter, setter), std::move(meminf))); } template class default_uniform_type_info : public detail::abstract_uniform_type_info { public: using super = detail::abstract_uniform_type_info; template default_uniform_type_info(std::string tname, Ts&&... xs) : super(std::move(tname)) { push_back(std::forward(xs)...); } default_uniform_type_info(std::string tname) : super(std::move(tname)) { using result_type = member_tinfo>; m_members.push_back(uniform_type_info_ptr(new result_type)); } void serialize(const void* obj, serializer* s) const override { // serialize each member for (auto& m : m_members) { m->serialize(obj, s); } } void deserialize(void* obj, deserializer* d) const override { // deserialize each member for (auto& m : m_members) { m->deserialize(obj, d); } } protected: bool pod_mems_equals(const T& lhs, const T& rhs) const override { return pod_eq(lhs, rhs); } private: template typename std::enable_if::value, bool>::type pod_eq(const C& lhs, const C& rhs) const { for (auto& member : m_members) { if (!member->equals(&lhs, &rhs)) return false; } return true; } template typename std::enable_if::value, bool>::type pod_eq(const C&, const C&) const { return false; } inline void push_back() { // terminate recursion } template void push_back(R C::*memptr, Ts&&... xs) { m_members.push_back(new_member_tinfo(memptr)); push_back(std::forward(xs)...); } // pr.first = member pointer // pr.second = meta object to handle pr.first template void push_back(const std::pair*>& pr, Ts&&... xs) { m_members.push_back(new_member_tinfo(pr.first, uniform_type_info_ptr(pr.second))); push_back(std::forward(xs)...); } // pr.first = const-qualified getter // pr.second = setter with one argument template void push_back(const std::pair& pr, Ts&&... xs) { m_members.push_back(new_member_tinfo(pr.first, pr.second)); push_back(std::forward(xs)...); } // pr.first = pair of const-qualified getter and setter with one argument // pr.second = uniform type info pointer template void push_back(const std::pair< std::pair, detail::abstract_uniform_type_info< typename std::decay::type>* >& pr, Ts&&... xs) { m_members.push_back(new_member_tinfo(pr.first.first, pr.first.second, uniform_type_info_ptr(pr.second))); push_back(std::forward(xs)...); } std::vector m_members; }; template class default_uniform_type_info> : public detail::abstract_uniform_type_info> { public: using super = detail::abstract_uniform_type_info>; using handle_type = typed_actor; default_uniform_type_info(std::string tname) : super(std::move(tname)) { sub_uti = uniform_typeid(); } void serialize(const void* obj, serializer* s) const override { auto tmp = actor_cast(deref(obj).address()); sub_uti->serialize(&tmp, s); } void deserialize(void* obj, deserializer* d) const override { actor tmp; sub_uti->deserialize(&tmp, d); deref(obj) = actor_cast(tmp); } private: static handle_type& deref(void* ptr) { return *reinterpret_cast(ptr); } static const handle_type& deref(const void* ptr) { return *reinterpret_cast(ptr); } const uniform_type_info* sub_uti; }; } // namespace detail } // namespace caf #endif // CAF_DETAIL_DEFAULT_UNIFORM_TYPE_INFO_IMPL_HPP actor-framework-0.13.2/libcaf_core/caf/detail/disablable_delete.hpp000066400000000000000000000036451251275671500252630ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_DETAIL_DISABLABLE_DELETE_HPP #define CAF_DETAIL_DISABLABLE_DELETE_HPP namespace caf { namespace detail { class disablable_delete { public: constexpr disablable_delete() : m_enabled(true) {} inline void disable() { m_enabled = false; } inline void enable() { m_enabled = true; } template inline void operator()(T* ptr) { if (m_enabled) delete ptr; } private: bool m_enabled; }; } // namespace detail } // namespace caf #endif // CAF_DETAIL_DISABLABLE_DELETE_HPP actor-framework-0.13.2/libcaf_core/caf/detail/disposer.hpp000066400000000000000000000033611251275671500235020ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_DETAIL_DISPOSER_HPP #define CAF_DETAIL_DISPOSER_HPP #include "caf/memory_managed.hpp" namespace caf { namespace detail { class disposer { public: inline void operator()(memory_managed* ptr) const { ptr->request_deletion(false); } }; } // namespace detail } // namespace caf #endif // CAF_DETAIL_DISPOSER_HPP actor-framework-0.13.2/libcaf_core/caf/detail/double_ended_queue.hpp000066400000000000000000000163431251275671500254730ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_DETAIL_DOUBLE_ENDED_QUEUE_HPP #define CAF_DETAIL_DOUBLE_ENDED_QUEUE_HPP #include "caf/config.hpp" #define CAF_CACHE_LINE_SIZE 64 #include #include #include #include // GCC hack #if defined(CAF_GCC) && !defined(_GLIBCXX_USE_SCHED_YIELD) #include namespace std { namespace this_thread { namespace { inline void yield() noexcept { timespec req; req.tv_sec = 0; req.tv_nsec = 1; nanosleep(&req, nullptr); } } // namespace anonymous> } // namespace this_thread } // namespace std #endif // another GCC hack #if defined(CAF_GCC) && !defined(_GLIBCXX_USE_NANOSLEEP) #include namespace std { namespace this_thread { namespace { template inline void sleep_for(const chrono::duration& rt) { auto sec = chrono::duration_cast(rt); auto nsec = chrono::duration_cast(rt - sec); timespec req; req.tv_sec = sec.count(); req.tv_nsec = nsec.count(); nanosleep(&req, nullptr); } } // namespace anonymous> } // namespace this_thread } // namespace std #endif namespace caf { namespace detail { /* * A thread-safe double-ended queue based on http://drdobbs.com/cpp/211601363. * This implementation is optimized for FIFO, i.e., it supports fast insertion * at the end and fast removal from the beginning. As long as the queue is * only used for FIFO operations, readers do not block writers and vice versa. */ template class double_ended_queue { public: using value_type = T; using size_type = size_t; using difference_type = ptrdiff_t; using reference = value_type&; using const_reference = const value_type&; using pointer = value_type*; using const_pointer = const value_type*; class node { public: pointer value; std::atomic next; node(pointer val) : value(val), next(nullptr) { // nop } private: static constexpr size_type payload_size = sizeof(pointer) + sizeof(std::atomic); static constexpr size_type cline_size = CAF_CACHE_LINE_SIZE; static constexpr size_type pad_size = (cline_size * ((payload_size / cline_size) + 1)) - payload_size; // avoid false sharing static_assert(pad_size > 0, "invalid padding size calculated"); char pad[pad_size]; }; using unique_node_ptr = std::unique_ptr; static_assert(sizeof(node*) < CAF_CACHE_LINE_SIZE, "sizeof(node*) >= CAF_CACHE_LINE_SIZE"); double_ended_queue() { m_head_lock.clear(); m_tail_lock.clear(); auto ptr = new node(nullptr); m_head = ptr; m_tail = ptr; } ~double_ended_queue() { auto ptr = m_head.load(); while (ptr) { unique_node_ptr tmp{ptr}; ptr = tmp->next.load(); } } // acquires only one lock void append(pointer value) { CAF_ASSERT(value != nullptr); node* tmp = new node(value); lock_guard guard(m_tail_lock); // publish & swing last forward m_tail.load()->next = tmp; m_tail = tmp; } // acquires both locks void prepend(pointer value) { CAF_ASSERT(value != nullptr); node* tmp = new node(value); node* first = nullptr; // acquire both locks since we might touch m_last too lock_guard guard1(m_head_lock); lock_guard guard2(m_tail_lock); first = m_head.load(); CAF_ASSERT(first != nullptr); auto next = first->next.load(); // m_first always points to a dummy with no value, // hence we put the new element second if (next == nullptr) { // queue is empty CAF_ASSERT(first == m_tail); m_tail = tmp; } else { CAF_ASSERT(first != m_tail); tmp->next = next; } first->next = tmp; } // acquires only one lock, returns nullptr on failure pointer take_head() { unique_node_ptr first; pointer result = nullptr; { // lifetime scope of guard lock_guard guard(m_head_lock); first.reset(m_head.load()); node* next = first->next; if (next == nullptr) { // queue is empty first.release(); return nullptr; } // take it out of the node & swing first forward result = next->value; next->value = nullptr; m_head = next; } return result; } // acquires both locks, returns nullptr on failure pointer take_tail() { pointer result = nullptr; unique_node_ptr last; { // lifetime scope of guards lock_guard guard1(m_head_lock); lock_guard guard2(m_tail_lock); CAF_ASSERT(m_head != nullptr); last.reset(m_tail.load()); if (last.get() == m_head.load()) { last.release(); return nullptr; } result = last->value; m_tail = find_predecessor(last.get()); CAF_ASSERT(m_tail != nullptr); m_tail.load()->next = nullptr; } return result; } // does not lock bool empty() const { // atomically compares first and last pointer without locks return m_head == m_tail; } private: // precondition: *both* locks acquired node* find_predecessor(node* what) { for (auto i = m_head.load(); i != nullptr; i = i->next) { if (i->next == what) { return i; } } return nullptr; } // guarded by m_head_lock std::atomic m_head; char m_pad1[CAF_CACHE_LINE_SIZE - sizeof(node*)]; // guarded by m_tail_lock std::atomic m_tail; char m_pad2[CAF_CACHE_LINE_SIZE - sizeof(node*)]; // enforce exclusive access std::atomic_flag m_head_lock; std::atomic_flag m_tail_lock; class lock_guard { public: lock_guard(std::atomic_flag& lock) : m_lock(lock) { while (lock.test_and_set(std::memory_order_acquire)) { std::this_thread::yield(); } } ~lock_guard() { m_lock.clear(std::memory_order_release); } private: std::atomic_flag& m_lock; }; }; } // namespace detail } // namespace caf #endif // CAF_DETAIL_DOUBLE_ENDED_QUEUE_HPP actor-framework-0.13.2/libcaf_core/caf/detail/embedded.hpp000066400000000000000000000043441251275671500234050ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_DETAIL_EMBEDDED_HPP #define CAF_DETAIL_EMBEDDED_HPP #include "caf/ref_counted.hpp" #include "caf/intrusive_ptr.hpp" namespace caf { namespace detail { template class embedded final : public Base { public: template embedded(intrusive_ptr storage, Ts&&... xs) : Base(std::forward(xs)...), m_storage(std::move(storage)) { // nop } ~embedded() { // nop } void request_deletion(bool) noexcept override { intrusive_ptr guard; guard.swap(m_storage); // this code assumes that embedded is part of pair_storage<>, // i.e., this object lives inside a union! this->~embedded(); } protected: intrusive_ptr m_storage; }; } // namespace detail } // namespace caf #endif // CAF_DETAIL_EMBEDDED_HPP actor-framework-0.13.2/libcaf_core/caf/detail/functor_attachable.hpp000066400000000000000000000046361251275671500255100ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENCE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_FUNCTOR_ATTACHABLE_HPP #define CAF_FUNCTOR_ATTACHABLE_HPP #include "caf/attachable.hpp" #include "caf/detail/type_list.hpp" #include "caf/detail/type_traits.hpp" namespace caf { namespace detail { template ::arg_types>::value> struct functor_attachable : attachable { static_assert(Args == 2, "Only 1 and 2 arguments for F are supported"); F m_functor; functor_attachable(F arg) : m_functor(std::move(arg)) { // nop } void actor_exited(abstract_actor* self, uint32_t reason) override { m_functor(self, reason); } static constexpr size_t token_type = attachable::token::anonymous; }; template struct functor_attachable : attachable { F m_functor; functor_attachable(F arg) : m_functor(std::move(arg)) { // nop } void actor_exited(abstract_actor*, uint32_t reason) override { m_functor(reason); } }; } // namespace detail } // namespace caf #endif // CAF_FUNCTOR_ATTACHABLE_HPP actor-framework-0.13.2/libcaf_core/caf/detail/get_mac_addresses.hpp000066400000000000000000000035271251275671500253120ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_DETAIL_GET_MAC_ADDRESSES_HPP #define CAF_DETAIL_GET_MAC_ADDRESSES_HPP #include #include #include namespace caf { namespace detail { using iface_info = std::pair; std::vector get_mac_addresses(); } // namespace detail } // namespace caf #endif // CAF_DETAIL_GET_MAC_ADDRESSES_HPP actor-framework-0.13.2/libcaf_core/caf/detail/get_root_uuid.hpp000066400000000000000000000032231251275671500245170ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_DETAIL_GET_ROOT_UUID_HPP #define CAF_DETAIL_GET_ROOT_UUID_HPP #include namespace caf { namespace detail { std::string get_root_uuid(); } // namespace detail } // namespace caf #endif // CAF_DETAIL_GET_ROOT_UUID_HPP actor-framework-0.13.2/libcaf_core/caf/detail/group_manager.hpp000066400000000000000000000046321251275671500245020ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_DETAIL_GROUP_MANAGER_HPP #define CAF_DETAIL_GROUP_MANAGER_HPP #include #include #include #include "caf/abstract_group.hpp" #include "caf/detail/shared_spinlock.hpp" #include "caf/detail/singleton_mixin.hpp" namespace caf { namespace detail { class group_manager { public: inline void dispose() { delete this; } static inline group_manager* create_singleton() { return new group_manager; } void stop(); inline void initialize() { // nop } ~group_manager(); group get(const std::string& module_name, const std::string& group_identifier); group anonymous(); void add_module(abstract_group::unique_module_ptr); abstract_group::module_ptr get_module(const std::string& module_name); private: using modules_map = std::map; group_manager(); modules_map m_mmap; std::mutex m_mmap_mtx; }; } // namespace detail } // namespace caf #endif // CAF_DETAIL_GROUP_MANAGER_HPP actor-framework-0.13.2/libcaf_core/caf/detail/ieee_754.hpp000066400000000000000000000123711251275671500231610ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ /******************************************************************************\ * Based on http://beej.us/guide/bgnet/examples/pack2.c * \ ******************************************************************************/ #ifndef CAF_DETAIL_IEEE_754_HPP #define CAF_DETAIL_IEEE_754_HPP #include #include namespace caf { namespace detail { template struct ieee_754_trait; template <> struct ieee_754_trait { static constexpr uint32_t bits = 32; // number of bits static constexpr uint32_t expbits = 8; // bits used for exponent static constexpr float zero = 0.0f; // the value 0 static constexpr float p5 = 0.5f; // the value 0.5 using packed_type = uint32_t; // unsigned integer type using signed_packed_type = int32_t; // signed integer type using float_type = float; // floating point type }; template <> struct ieee_754_trait : ieee_754_trait {}; template <> struct ieee_754_trait { static constexpr uint64_t bits = 64; static constexpr uint64_t expbits = 11; static constexpr double zero = 0.0; static constexpr double p5 = 0.5; using packed_type = uint64_t; using signed_packed_type = int64_t; using float_type = double; }; template <> struct ieee_754_trait : ieee_754_trait {}; template typename ieee_754_trait::packed_type pack754(T f) { typedef ieee_754_trait trait; // using trait = ... fails on GCC 4.7 using result_type = typename trait::packed_type; // filter special type if (std::fabs(f) <= trait::zero) { return 0; // only true if f equals +0 or -0 } auto significandbits = trait::bits - trait::expbits - 1; // -1 for sign bit // check sign and begin normalization result_type sign; T fnorm; if (f < 0) { sign = 1; fnorm = -f; } else { sign = 0; fnorm = f; } // get the normalized form of f and track the exponent typename ieee_754_trait::packed_type shift = 0; while (fnorm >= static_cast(2)) { fnorm /= static_cast(2); ++shift; } while (fnorm < static_cast(1)) { fnorm *= static_cast(2); --shift; } fnorm = fnorm - static_cast(1); // calculate 2^significandbits auto pownum = static_cast(result_type{1} << significandbits); // calculate the binary form (non-float) of the significand data auto significand = static_cast(fnorm * (pownum + trait::p5)); // get the biased exponent auto exp = shift + ((1 << (trait::expbits - 1)) - 1); // shift + bias // return the final answer return (sign << (trait::bits - 1)) | (exp << (trait::bits - trait::expbits - 1)) | significand; } template typename ieee_754_trait::float_type unpack754(T i) { typedef ieee_754_trait trait; // using trait = ... fails on GCC 4.7 using signed_type = typename trait::signed_packed_type; using result_type = typename trait::float_type; if (i == 0) return trait::zero; auto significandbits = trait::bits - trait::expbits - 1; // -1 for sign bit // pull the significand: mask, convert back to float + add the one back on auto result = static_cast(i & ((T{1} << significandbits) - 1)); result /= static_cast(T{1} << significandbits); result += static_cast(1); // deal with the exponent auto si = static_cast(i); auto bias = (1 << (trait::expbits - 1)) - 1; auto pownum = static_cast(1) << trait::expbits; auto shift = static_cast( ((si >> significandbits) & (pownum - 1)) - bias); while (shift > 0) { result *= static_cast(2); --shift; } while (shift < 0) { result /= static_cast(2); ++shift; } // sign it result *= (i >> (trait::bits - 1)) & 1 ? -1 : 1; return result; } } // namespace detail } // namespace caf #endif // CAF_DETAIL_IEEE_754_HPP actor-framework-0.13.2/libcaf_core/caf/detail/implicit_conversions.hpp000066400000000000000000000055041251275671500261150ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_DETAIL_IMPLICIT_CONVERSIONS_HPP #define CAF_DETAIL_IMPLICIT_CONVERSIONS_HPP #include #include #include "caf/fwd.hpp" #include "caf/detail/type_traits.hpp" namespace caf { namespace detail { template struct implicit_conversions { // convert C strings to std::string if possible using step1 = typename replace_type< T, std::string, std::is_same, std::is_same, std::is_same, is_array_of, is_array_of >::type; // convert C strings to std::u16string if possible using step2 = typename replace_type< step1, std::u16string, std::is_same, std::is_same, is_array_of >::type; // convert C strings to std::u32string if possible using step3 = typename replace_type< step2, std::u32string, std::is_same, std::is_same, is_array_of >::type; using type = typename replace_type< step3, actor, std::is_convertible, std::is_same >::type; }; template struct strip_and_convert { using type = typename implicit_conversions< typename std::decay::type >::type; }; } // namespace detail } // namespace caf #endif // CAF_DETAIL_IMPLICIT_CONVERSIONS_HPP actor-framework-0.13.2/libcaf_core/caf/detail/int_list.hpp000066400000000000000000000075211251275671500235010ustar00rootroot00000000000000/****************************************************************************** * ____ _ _____ * * / ___| / \ | ___| C++ * * | | / _ \ | |_ Actor * * | |___ / ___ \| _| Framework * * \____/_/ \_|_| * * * * Copyright (C) 2011 - 2015 * * Dominik Charousset * * * * Distributed under the terms and conditions of the BSD 3-Clause License or * * (at your option) under the terms and conditions of the Boost Software * * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. * * * * If you did not receive a copy of the license files, see * * http://opensource.org/licenses/BSD-3-Clause and * * http://www.boost.org/LICENSE_1_0.txt. * ******************************************************************************/ #ifndef CAF_DETAIL_INT_LIST_HPP #define CAF_DETAIL_INT_LIST_HPP #include "caf/detail/type_list.hpp" namespace caf { namespace detail { /** * A list of integers (wraps a long... template parameter pack). */ template struct int_list {}; template struct il_right_impl; template struct il_right_impl { using type = int_list<>; }; template struct il_right_impl : il_right_impl { }; template struct il_right_impl { using type = int_list; }; template struct il_right; template struct il_right, N> { using type = typename il_right_impl<(N > sizeof...(Is) ? sizeof...(Is) : N), sizeof...(Is), Is...>::type; }; template struct il_take_impl; template struct il_take_impl { using type = List; }; template struct il_take_impl, I, Is...> { using type = typename il_take_impl, Is...>::type; }; template struct il_take; template struct il_take, N> { using type = typename il_take_impl, Is...>::type; }; /** * Creates indices for `List` beginning at `Pos`. */ template > struct il_indices; template