├── .gitignore ├── .tgitconfig ├── CMakeLists.txt ├── CTestCustom.cmake.in ├── README.md ├── cmake ├── CMakeLists.txt ├── CheckCXXConcepts.cmake ├── CheckCXXSymbolExists.cmake ├── CheckSymbolExists.cxx.in ├── CompileTestDriver.cmake.in ├── GenerateExportHeader.cmake ├── OriginConfig.cmake.in ├── OriginTesting.cmake ├── OriginUtilities.cmake └── exportheader.cmake.in ├── cmake_uninstall.cmake.in ├── examples ├── hello │ ├── CMakeLists.txt │ └── hello.cpp └── origin.math │ ├── moving_means.cpp │ ├── moving_sums │ └── moving_sums.cpp ├── origin.graph ├── CMakeLists.txt ├── adjacency_list.cpp ├── adjacency_list.hpp ├── adjacency_list.impl │ └── pool.hpp ├── adjacency_list.test │ ├── CMakeLists.txt │ ├── adjacency_list.cpp │ └── pool.cpp ├── adjacency_vector.cpp ├── adjacency_vector.hpp ├── adjacency_vector.test │ └── adjacency_vector.cpp ├── concepts.hpp ├── config.hpp.in ├── edge.hpp ├── graph.hpp ├── graph.test │ └── testing.hpp ├── handle.hpp ├── handle.test │ ├── CMakeLists.txt │ └── handle.cpp └── io.hpp ├── origin.math ├── CMakeLists.txt ├── config.hpp.in ├── numeric.cpp ├── numeric.hpp ├── stats.cpp └── stats.hpp └── origin ├── CMakeLists.txt ├── algorithm.hpp ├── algorithm ├── CMakeLists.txt ├── algorithm.test │ ├── CMakeLists.txt │ ├── adjacent_find.cpp │ ├── all_of.cpp │ ├── any_of.cpp │ ├── copy.cpp │ ├── count.cpp │ ├── count_if.cpp │ ├── equal.cpp │ ├── find.cpp │ ├── find_end.cpp │ ├── find_first_of.cpp │ ├── find_if.cpp │ ├── find_if_not.cpp │ ├── for_each.cpp │ ├── mismatch.cpp │ └── none_of.cpp ├── concepts.cpp ├── concepts.hpp ├── config.hpp.in ├── copy.cpp ├── copy.hpp ├── count.cpp ├── count.hpp ├── equal.cpp ├── equal.hpp ├── find.cpp ├── find.hpp ├── foreach.cpp ├── foreach.hpp ├── quantifier.cpp ├── quantifier.hpp ├── uninitialized.cpp └── uninitialized.hpp ├── core ├── CMakeLists.txt ├── concepts.cpp ├── concepts.hpp ├── concepts.test │ ├── CMakeLists.txt │ ├── assignable.cpp │ ├── binary_operation.cpp │ ├── boolean.cpp │ ├── character.cpp │ ├── common.cpp │ ├── common_type.cpp │ ├── constructible.cpp │ ├── convertible.cpp │ ├── copy_assignable.cpp │ ├── copy_constructible.cpp │ ├── copyable.cpp │ ├── default_constructible.cpp │ ├── derived.cpp │ ├── destructible.cpp │ ├── difference_type.cpp │ ├── equality_comparable.cpp │ ├── function.cpp │ ├── integral.cpp │ ├── movable.cpp │ ├── move_assignable.cpp │ ├── move_constructible.cpp │ ├── ordered.cpp │ ├── predicate.cpp │ ├── regular.cpp │ ├── relation.cpp │ ├── same.cpp │ ├── semiregular.cpp │ ├── signed_integer.cpp │ ├── totally_ordered.cpp │ ├── unary_operation.cpp │ ├── unsigned_integer.cpp │ ├── value_type.cpp │ ├── void.cpp │ └── weakly_ordered.cpp ├── config.hpp.in ├── finally.cpp ├── finally.hpp ├── finally.test │ ├── CMakeLists.txt │ └── finally.cpp ├── function.cpp ├── function.hpp ├── function.test │ ├── CMakeLists.txt │ └── invoke.cpp ├── semantics.cpp ├── semantics.hpp ├── traits.cpp ├── traits.hpp ├── type.cpp └── type.hpp ├── data ├── CMakeLists.txt ├── config.hpp.in ├── vector.cpp └── vector.hpp ├── functional.hpp ├── generic.hpp ├── iterator.hpp ├── iterator ├── CMakeLists.txt ├── config.hpp.in ├── core.cpp ├── core.hpp └── core.test │ ├── CMakeLists.txt │ ├── advanceable.cpp │ ├── bidirectional_iterator.cpp │ ├── forward_iterator.cpp │ ├── incrementable.cpp │ ├── input_iterator.cpp │ ├── mutable.cpp │ ├── output_iterator.cpp │ ├── permutable.cpp │ ├── random_access_iterator.cpp │ ├── readable.cpp │ ├── test_iterator.hpp │ ├── test_resource.hpp │ ├── value_type.cpp │ └── writable.cpp ├── memory.hpp ├── memory ├── CMakeLists.txt ├── allocator.cpp ├── allocator.hpp ├── config.hpp.in ├── memory.cpp └── memory.hpp ├── numeric ├── CMakeLists.txt ├── algebra.cpp ├── algebra.hpp ├── algebra.test │ ├── CMakeLists.txt │ └── foldl.cpp ├── config.hpp.in ├── numeric.cpp └── numeric.hpp ├── origin.cpp ├── range.hpp └── range ├── CMakeLists.txt ├── config.hpp.in ├── core.cpp ├── core.hpp ├── core.test ├── CMakeLists.txt ├── bidirectional_range.cpp ├── forward_range.cpp ├── input_range.cpp ├── iterator_type.cpp ├── output_range.cpp ├── random_access_range.cpp ├── range.cpp ├── sentinel_type.cpp ├── size_type.cpp ├── test_resource.hpp └── value_type.cpp ├── range.cpp ├── range.hpp └── range.test ├── CMakeLists.txt ├── bounded.cpp └── size.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | *.a 2 | *.dSYM/ 3 | *.dll 4 | *.dylib 5 | *.exe 6 | *.la 7 | *.lai 8 | *.lib 9 | *.lo 10 | *.o 11 | *.obj 12 | *.out 13 | *.rej 14 | *.slo 15 | *.so 16 | *.so.[0-9]* 17 | *.stackdump 18 | *~ 19 | .*.swp 20 | .libs 21 | 22 | # OS 23 | .DS_Store 24 | .DS_Store? 25 | .Spotlight-V100 26 | .Trashes 27 | ._* 28 | Thumbs.db 29 | ehthumbs.db 30 | 31 | # CMake 32 | CMakeCache.txt 33 | CMakeFiles/ 34 | CTestTestfile.cmake 35 | Makefile 36 | Testing/ 37 | cmake_install.cmake 38 | compile_commands.json 39 | install_manifest.txt 40 | 41 | # Origin 42 | CTestCustom.cmake 43 | CompileTestDriver.cmake 44 | OriginConfig.cmake 45 | OriginConfigVersion.cmake 46 | OriginTargets.cmake 47 | cmake_uninstall.cmake 48 | config.hpp 49 | export.hpp 50 | -------------------------------------------------------------------------------- /.tgitconfig: -------------------------------------------------------------------------------- 1 | [bugtraq] 2 | url = https://github.com/asutton/origin/issues/%BUGID% 3 | warnifnoissue = false 4 | logregex = "#\\d+|GH-\\d+|asutton(/origin)?#\\d+\n\\d+" 5 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2009-2015 Andrew Sutton 2 | # All rights reserved 3 | 4 | cmake_minimum_required(VERSION 3.0) 5 | 6 | # Set CMake module path. 7 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) 8 | 9 | include(CheckCXXCompilerFlag) 10 | include(CheckCXXConcepts) 11 | include(CMakePackageConfigHelpers) 12 | include(GNUInstallDirs) 13 | include(OriginTesting) 14 | include(OriginUtilities) 15 | 16 | # Add a project. 17 | project(Origin VERSION 0.1 LANGUAGES CXX) 18 | 19 | # Set variables. 20 | set(ORIGIN_PACKAGE_NAME ${PROJECT_NAME}) 21 | set(ORIGIN_PACKAGE_TARNAME ${ORIGIN_PACKAGE_NAME}) 22 | set(ORIGIN_PACKAGE_VERSION ${PROJECT_VERSION}) 23 | set(ORIGIN_PACKAGE_STRING "${ORIGIN_PACKAGE_NAME} ${ORIGIN_PACKAGE_VERSION}") 24 | set(ORIGIN_PACKAGE_BUGREPORT "https://github.com/asutton/origin/issues") 25 | set(ORIGIN_PACKAGE_URL "https://github.com/asutton/origin") 26 | set(ORIGIN_VERSION ${PROJECT_VERSION}) 27 | 28 | foreach(component MAJOR MINOR PATCH TWEAK) 29 | if(PROJECT_VERSION_${component} STREQUAL "") 30 | set(PROJECT_VERSION_${component} 0) 31 | endif() 32 | endforeach() 33 | 34 | set(ORIGIN_VERSION_MAJOR ${PROJECT_VERSION_MAJOR}) 35 | set(ORIGIN_VERSION_MINOR ${PROJECT_VERSION_MINOR}) 36 | set(ORIGIN_VERSION_PATCH ${PROJECT_VERSION_PATCH}) 37 | set(ORIGIN_VERSION_TWEAK ${PROJECT_VERSION_TWEAK}) 38 | 39 | set(INSTALL_BIN_DIR ${CMAKE_INSTALL_BINDIR}) 40 | set(INSTALL_LIB_DIR ${CMAKE_INSTALL_LIBDIR}) 41 | set(INSTALL_INCLUDE_DIR ${CMAKE_INSTALL_INCLUDEDIR}) 42 | set(INSTALL_DATA_DIR ${CMAKE_INSTALL_DATADIR}) 43 | 44 | # Add .ipp and .IPP to list of ignored file extensions for C++. 45 | list(APPEND CMAKE_CXX_IGNORE_EXTENSIONS "ipp" "IPP") 46 | list(REMOVE_DUPLICATES CMAKE_CXX_IGNORE_EXTENSIONS) 47 | 48 | # Set output location of built targets. 49 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) 50 | # set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) 51 | # set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) 52 | 53 | # Add options. 54 | option(BUILD_SHARED_LIBS "Build shared libraries." ON) 55 | 56 | # Enable testing. 57 | enable_testing() 58 | 59 | # Run platform checks. 60 | # Make sure that we have C++1z... 61 | check_cxx_compiler_flag(-std=c++1z CXX_COMPILER_HAS_STDCXX1Z_FLAG) 62 | if(NOT CXX_COMPILER_HAS_STDCXX1Z_FLAG) 63 | message(FATAL_ERROR "${PROJECT_NAME} requires a C++ compiler that supports -std=c++1z.") 64 | endif() 65 | 66 | # ... and that concepts are included in C++1z. 67 | # TODO: What happens when there are different versions of concepts? 68 | set(CMAKE_REQUIRED_FLAGS -fconcepts) 69 | check_cxx_concepts(CXX_COMPILER_HAS_CONCEPTS) 70 | if(NOT CXX_COMPILER_HAS_CONCEPTS) 71 | message(FATAL_ERROR "${PROJECT_NAME} requires a C++ compiler that supports concepts.") 72 | endif() 73 | 74 | # Set compiler and linker flags. 75 | 76 | # Generate the compilation test driver script. 77 | generate_compile_test_driver(CompileTestDriver.cmake) 78 | 79 | # Generate CTest custom script. 80 | configure_file(CTestCustom.cmake.in CTestCustom.cmake @ONLY) 81 | 82 | # Add 'check' target. 83 | if(NOT TARGET check) 84 | add_custom_target( 85 | check 86 | COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target test 87 | ) 88 | endif() 89 | 90 | # Add 'uninstall' target. 91 | if(NOT TARGET uninstall) 92 | configure_file( 93 | ${PROJECT_SOURCE_DIR}/cmake_uninstall.cmake.in 94 | ${CMAKE_BINARY_DIR}/cmake_uninstall.cmake 95 | @ONLY 96 | ) 97 | add_custom_target( 98 | uninstall 99 | COMMAND ${CMAKE_COMMAND} -P ${CMAKE_BINARY_DIR}/cmake_uninstall.cmake 100 | ) 101 | endif() 102 | 103 | # Add subdirectories. 104 | add_subdirectory(origin) 105 | add_subdirectory(origin.math) 106 | add_subdirectory(examples/hello) 107 | add_subdirectory(cmake) 108 | 109 | # Export targets from the build tree. 110 | export(EXPORT OriginTargets) 111 | 112 | # Add install targets. 113 | install( 114 | DIRECTORY ${PROJECT_SOURCE_DIR}/origin ${PROJECT_BINARY_DIR}/origin 115 | DESTINATION ${INSTALL_INCLUDE_DIR} 116 | FILES_MATCHING 117 | PATTERN "*.hpp" 118 | PATTERN "*.ipp" 119 | PATTERN "CMakeFiles" EXCLUDE 120 | PATTERN "*.test" EXCLUDE 121 | ) 122 | -------------------------------------------------------------------------------- /CTestCustom.cmake.in: -------------------------------------------------------------------------------- 1 | # CTest custom script for 2 | # Source directory: @CMAKE_CURRENT_SOURCE_DIR@ 3 | # Build directory: @CMAKE_CURRENT_BINARY_DIR@ 4 | 5 | # See http://www.cmake.org/Wiki/CMake/Testing_With_CTest and 6 | # http://www.kitware.com/blog/home/post/27 for more information regarding 7 | # this file. 8 | 9 | set(CTEST_CUSTOM_ERROR_MATCH 10 | ${CTEST_CUSTOM_ERROR_MATCH} 11 | 12 | # Include diagnostic messages of the form 13 | # "::: error: " (GCC, Clang...) 14 | "^.+:[0-9]+:[0-9]+: error: .+$" 15 | ) 16 | 17 | set(CTEST_CUSTOM_ERROR_EXCEPTION 18 | ${CTEST_CUSTOM_ERROR_EXCEPTION} 19 | 20 | # Exclude messages like 21 | # "g++: error: CMakeFiles/.dir/.cpp.o: No such file or directory" 22 | "^.*g\\+\\+.*: error: .+$" 23 | ) 24 | 25 | set(CTEST_CUSTOM_WARNING_MATCH 26 | ${CTEST_CUSTOM_WARNING_MATCH} 27 | 28 | # Include diagnostic messages of the form 29 | # "::: warning: " (GCC, Clang...) 30 | "^.+:[0-9]+:[0-9]+: warning: .+$" 31 | ) 32 | 33 | list(APPEND CTEST_EXTRA_COVERAGE_GLOB "*.cpp" "*.hpp" "*.ipp") 34 | list(REMOVE_DUPLICATES CTEST_EXTRA_COVERAGE_GLOB) 35 | 36 | set(CTEST_CUSTOM_COVERAGE_EXCLUDE 37 | ${CTEST_CUSTOM_COVERAGE_EXCLUDE} 38 | 39 | # Exclude try_compile sources from coverage results: 40 | "/CMakeFiles/CMakeTmp/" 41 | 42 | # Exclude tests: 43 | "/.*\\.test/" 44 | ) 45 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Origin 2 | ====== 3 | 4 | The Origin libraries are a collection of libraries written using the 5 | latest features of the C++ programming language. They are designed 6 | to wrap the C++ standard library and provide replacements for older 7 | features and new experimental features. The goal of this work is 8 | to foster experimentation in library design and to serve as a data 9 | point for the standardization efforts within C++. 10 | 11 | Currently, this site serves two primary purposes: to document the 12 | evolution and usage of concepts, as documented in the ISO Concepts TS, 13 | and to provide a basic set of facilities based on that language feature. 14 | 15 | Work is currently focused on the use of concepts to specify and 16 | implement a new version of the C++ standard library. Note that this 17 | work is independent of the ISO Ranges TS (STLv2), although many ideas 18 | overlap. Because the Origin libraries are experimental, certain 19 | facilities may be quite different than those proposed for the C++ 20 | standard (generally simpler). 21 | 22 | More information can be found on the 23 | [GitHib Pages website](http://asutton.github.io/origin). 24 | -------------------------------------------------------------------------------- /cmake/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(INSTALL_PACKAGE_DIR ${INSTALL_DATA_DIR}/origin-${Origin_VERSION_MAJOR}.${Origin_VERSION_MINOR}/cmake) 2 | 3 | # Generate package configuration and version files. 4 | configure_package_config_file( 5 | OriginConfig.cmake.in 6 | OriginConfig.cmake 7 | INSTALL_DESTINATION ${INSTALL_PACKAGE_DIR} 8 | PATH_VARS INSTALL_BIN_DIR INSTALL_LIB_DIR INSTALL_INCLUDE_DIR 9 | ) 10 | write_basic_package_version_file( 11 | OriginConfigVersion.cmake 12 | COMPATIBILITY AnyNewerVersion 13 | ) 14 | 15 | # Export targets from the installation tree. 16 | install(EXPORT OriginTargets DESTINATION ${INSTALL_PACKAGE_DIR}) 17 | 18 | # Install OriginConfig.cmake and OriginConfigVersion.cmake files. 19 | install( 20 | FILES 21 | ${CMAKE_CURRENT_BINARY_DIR}/OriginConfig.cmake 22 | ${CMAKE_CURRENT_BINARY_DIR}/OriginConfigVersion.cmake 23 | DESTINATION ${INSTALL_PACKAGE_DIR} 24 | ) 25 | -------------------------------------------------------------------------------- /cmake/CheckCXXConcepts.cmake: -------------------------------------------------------------------------------- 1 | #.rst: 2 | # CheckCXXConcepts 3 | # ---------------- 4 | # 5 | # Check if the C++ compiler supports constraints for template arguments (i.e. 6 | # `concepts `_). 7 | # 8 | # :: 9 | # 10 | # check_cxx_concepts() 11 | # 12 | # ```` 13 | # The variable that will store the result. 14 | # 15 | # The following variables may be set before calling this macro to modify the 16 | # way the check is run: 17 | # 18 | # ``CMAKE_REQUIRED_FLAGS`` 19 | # String of compile command line flags. 20 | # ``CMAKE_REQUIRED_DEFINITIONS`` 21 | # List of macros to define (-DFOO=bar). 22 | # ``CMAKE_REQUIRED_INCLUDES`` 23 | # List of include directories. 24 | # ``CMAKE_REQUIRED_LIBRARIES`` 25 | # List of libraries to link. 26 | # ``CMAKE_REQUIRED_QUIET`` 27 | # Execute quietly without messages. 28 | # 29 | # .. note:: 30 | # As of 2015, the only known compiler that supports this language feature 31 | # is `GCC 6.0 `_. 32 | # 33 | # Requires CMake 2.8 or later. 34 | 35 | include(CheckCXXSourceCompiles) 36 | 37 | macro(CHECK_CXX_CONCEPTS VARIABLE) 38 | check_cxx_source_compiles(" 39 | template 40 | concept bool 41 | Equality_comparable() { 42 | return requires (T a, T b) { 43 | { a == b } -> bool; 44 | { a != b } -> bool; 45 | }; 46 | } 47 | 48 | int main() { 49 | return 0; 50 | } 51 | " ${VARIABLE}) 52 | endmacro() 53 | -------------------------------------------------------------------------------- /cmake/CheckSymbolExists.cxx.in: -------------------------------------------------------------------------------- 1 | @INCLUDES@ 2 | 3 | int main() { 4 | #ifndef @SYMBOL_NAME@ 5 | @ARG_DECLARATIONS@ 6 | (void)@SYMBOL_USE@; 7 | #endif 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /cmake/CompileTestDriver.cmake.in: -------------------------------------------------------------------------------- 1 | # Compilation test driver script for 2 | # Project: @PROJECT_NAME@ 3 | # Source directory: @PROJECT_SOURCE_DIR@ 4 | # Build directory: @PROJECT_BINARY_DIR@ 5 | 6 | # Usage: ${CMAKE_COMMAND} -P ${CMAKE_SCRIPT_MODE_FILE} ... 7 | 8 | set(CMAKE_MODULE_PATH "@Origin_SOURCE_DIR@/cmake") 9 | 10 | include(OriginUtilities) 11 | 12 | # Initialize variables used in this script. 13 | get_filename_component(CMAKE_FILES_DIRECTORY_NAME ${CMAKE_FILES_DIRECTORY} NAME) 14 | 15 | if("@CMAKE_GENERATOR@" MATCHES "Make") 16 | # Use -k instead of -i for Makefile generators. 17 | set(NATIVE_TOOL_OPTIONS -k) 18 | endif() 19 | 20 | if(DEFINED NATIVE_TOOL_OPTIONS) 21 | set(CMAKE_BUILD_ADD_NATIVE_TOOL_OPTIONS -- ${NATIVE_TOOL_OPTIONS}) 22 | endif() 23 | 24 | # In the top-level build directory, read CTestCustom.cmake if it exists; 25 | # otherwise, read CTestCustom.ctest. 26 | include("@CMAKE_BINARY_DIR@/CTestCustom.cmake" 27 | RESULT_VARIABLE CTEST_CUSTOM_FILE 28 | OPTIONAL) 29 | if(NOT CTEST_CUSTOM_FILE) 30 | include("@CMAKE_BINARY_DIR@/CTestCustom.ctest" 31 | RESULT_VARIABLE CTEST_CUSTOM_FILE 32 | OPTIONAL) 33 | # If CTestCustom.ctest file exists, recursively scan subdirectories for 34 | # additional CTestCustom.ctest files and read those, too. 35 | if(CTEST_CUSTOM_FILE) 36 | file(GLOB_RECURSE CTEST_CUSTOM_FILES 37 | "@CMAKE_BINARY_DIR@/*/CTestCustom.ctest") 38 | foreach(file ${CTEST_CUSTOM_FILES}) 39 | include(${file}) 40 | endforeach() 41 | endif() 42 | endif() 43 | 44 | foreach(var ERROR_MATCH ERROR_EXCEPTION WARNING_MATCH WARNING_EXCEPTION) 45 | foreach(regex ${CTEST_CUSTOM_${var}}) 46 | list(APPEND COMPILE_${var} "(${regex})") 47 | endforeach() 48 | string_join(COMPILE_${var} "|" ${COMPILE_${var}}) 49 | endforeach() 50 | 51 | # Parse command-line arguments. 52 | set(i 0) 53 | while(i LESS CMAKE_ARGC) 54 | if(CMAKE_ARGV${i} STREQUAL "-P") 55 | math(EXPR i "${i} + 2") 56 | break() 57 | endif() 58 | math(EXPR i "${i} + 1") 59 | endwhile() 60 | if(NOT i LESS CMAKE_ARGC) 61 | message(FATAL_ERROR "A build configuration must be specified.") 62 | endif() 63 | set(CONFIGURATION_TYPE ${CMAKE_ARGV${i}}) 64 | if(NOT CONFIGURATION_TYPE STREQUAL "") 65 | set(CMAKE_BUILD_ADD_CONFIGURATION --config ${CONFIGURATION_TYPE}) 66 | endif() 67 | math(EXPR i "${i} + 1") 68 | while(i LESS CMAKE_ARGC) 69 | list(APPEND TARGETS ${CMAKE_ARGV${i}}) 70 | math(EXPR i "${i} + 1") 71 | endwhile() 72 | 73 | file(STRINGS "@CMAKE_BINARY_DIR@${CMAKE_FILES_DIRECTORY}/TargetDirectories.txt" 74 | TARGET_DIRECTORIES) 75 | 76 | # Process targets. 77 | foreach(target ${TARGETS}) 78 | # Find the clean script for the target. 79 | foreach(target_directory ${TARGET_DIRECTORIES}) 80 | string(REGEX MATCH 81 | "^@CMAKE_BINARY_DIR@(/.*)?${CMAKE_FILES_DIRECTORY}/${target}\\.dir$" 82 | TARGET_DIR ${target_directory}) 83 | if(TARGET_DIR) 84 | break() 85 | endif() 86 | endforeach() 87 | 88 | if(NOT TARGET_DIR) 89 | message(WARNING "Invalid target '${target}' (ignored).") 90 | else() 91 | string(REGEX REPLACE "${CMAKE_FILES_DIRECTORY}/${target}\\.dir$" "" 92 | TARGET_BINARY_DIR ${TARGET_DIR}) 93 | 94 | # Clean the target. 95 | message(STATUS "Cleaning target '${target}'") 96 | execute_process(COMMAND ${CMAKE_COMMAND} -P 97 | ${CMAKE_FILES_DIRECTORY_NAME}/${target}.dir/cmake_clean.cmake 98 | WORKING_DIRECTORY ${TARGET_BINARY_DIR} 99 | OUTPUT_QUIET ERROR_QUIET) 100 | message(STATUS "Cleaning target '${target}' - done") 101 | 102 | # Build the target. 103 | message(STATUS "Compiling target '${target}'") 104 | execute_process(COMMAND ${CMAKE_COMMAND} 105 | --build "@PROJECT_BINARY_DIR@" ${CMAKE_BUILD_ADD_CONFIGURATION} 106 | --target ${target} --use-stderr 107 | ${CMAKE_BUILD_ADD_NATIVE_TOOL_OPTIONS} 108 | RESULT_VARIABLE COMPILE_RESULT 109 | ERROR_VARIABLE COMPILE_ERROR_CONTENTS 110 | OUTPUT_QUIET 111 | ERROR_STRIP_TRAILING_WHITESPACE) 112 | string(REGEX MATCHALL "[^\r\n]*(\r|\n|\r\n)" COMPILE_ERROR_LINES 113 | "${COMPILE_ERROR_CONTENTS}") 114 | string(REGEX REPLACE "\r|\n|\r\n" "" COMPILE_ERROR_LINES 115 | "${COMPILE_ERROR_LINES}") 116 | foreach(compile_error_line ${COMPILE_ERROR_LINES}) 117 | foreach(var ERROR WARNING) 118 | if(compile_error_line MATCHES "${COMPILE_${var}_MATCH}") 119 | if(NOT DEFINED COMPILE_${var}_EXCEPTION 120 | OR (DEFINED COMPILE_${var}_EXCEPTION 121 | AND NOT compile_error_line MATCHES "${COMPILE_${var}_EXCEPTION}")) 122 | list(APPEND COMPILE_${var}S ${compile_error_line}) 123 | endif() 124 | endif() 125 | endforeach() 126 | endforeach() 127 | list(LENGTH COMPILE_ERRORS COMPILE_ERROR_COUNT) 128 | list(LENGTH COMPILE_WARNINGS COMPILE_WARNING_COUNT) 129 | if(NOT COMPILE_ERROR_COUNT EQUAL 1) 130 | set(COMPILE_ERROR_ADD_S s) 131 | endif() 132 | if(NOT COMPILE_WARNING_COUNT EQUAL 1) 133 | set(COMPILE_WARNING_ADD_S s) 134 | endif() 135 | if(COMPILE_ERROR_CONTENTS) 136 | message(${COMPILE_ERROR_CONTENTS}) 137 | endif() 138 | message(STATUS "Compiling target '${target}' - exited with status ${COMPILE_RESULT} (${COMPILE_ERROR_COUNT} error${COMPILE_ERROR_ADD_S}, ${COMPILE_WARNING_COUNT} warning${COMPILE_WARNING_ADD_S})") 139 | 140 | if(NOT COMPILE_RESULT EQUAL 0) 141 | list(APPEND FAILED_TARGETS ${target}) 142 | endif() 143 | endif() 144 | endforeach() 145 | 146 | if(NOT "${FAILED_TARGETS}" STREQUAL "") 147 | string_join(FAILED_TARGETS_LIST "\n\t" ${FAILED_TARGETS}) 148 | message(FATAL_ERROR "The following target(s) failed to compile:\n\t${FAILED_TARGETS_LIST}") 149 | endif() 150 | -------------------------------------------------------------------------------- /cmake/OriginConfig.cmake.in: -------------------------------------------------------------------------------- 1 | #.rst: 2 | # OriginConfig 3 | # ------------ 4 | # 5 | # Package configuration file for the Origin libraries. 6 | # 7 | # This file (along with the package version file OriginConfigVersion.cmake) 8 | # is loaded by the :command:`find_package` command and defines 9 | # targets/variables for CMake projects that use the Origin libraries. 10 | 11 | # TODO: Check for package dependencies. 12 | # include(CMakeFindDependencyMacro) 13 | 14 | @PACKAGE_INIT@ 15 | 16 | include(${CMAKE_CURRENT_LIST_DIR}/OriginTargets.cmake) 17 | 18 | set_and_check(Origin_INCLUDE_DIR "@PACKAGE_INSTALL_INCLUDE_DIR@") 19 | set_and_check(Origin_LIBRARY_DIR "@PACKAGE_INSTALL_LIB_DIR@") 20 | 21 | check_required_components(Origin) 22 | -------------------------------------------------------------------------------- /cmake/OriginUtilities.cmake: -------------------------------------------------------------------------------- 1 | #.rst: 2 | # OriginUtilities 3 | # --------------- 4 | # 5 | # Various utility macros and functions. 6 | # 7 | # :: 8 | # 9 | # string_join( [...]) 10 | # 11 | # Concatenates all the input arguments together, using the specified 12 | # separator string between each element. The result is stored in the named 13 | # output variable. 14 | # 15 | # Requires CMake 2.8 or later. 16 | 17 | function(STRING_JOIN VARIABLE SEPARATOR) 18 | set(${VARIABLE}) 19 | if(ARGC GREATER 2) 20 | list(LENGTH ARGN n) 21 | math(EXPR n-1 "${n} - 1") 22 | foreach(i RANGE ${n-1}) 23 | list(GET ARGN ${i} ARG) 24 | set(${VARIABLE} "${${VARIABLE}}${ARG}") 25 | if(i LESS n-1) 26 | set(${VARIABLE} "${${VARIABLE}}${SEPARATOR}") 27 | endif() 28 | endforeach() 29 | endif() 30 | set(${VARIABLE} ${${VARIABLE}} PARENT_SCOPE) 31 | endfunction() 32 | -------------------------------------------------------------------------------- /cmake/exportheader.cmake.in: -------------------------------------------------------------------------------- 1 | 2 | #ifndef @INCLUDE_GUARD_NAME@ 3 | #define @INCLUDE_GUARD_NAME@ 4 | 5 | #ifdef @STATIC_DEFINE@ 6 | # define @EXPORT_MACRO_NAME@ 7 | # define @NO_EXPORT_MACRO_NAME@ 8 | #else 9 | # ifndef @EXPORT_MACRO_NAME@ 10 | # ifdef @EXPORT_IMPORT_CONDITION@ 11 | /* We are building this library */ 12 | # define @EXPORT_MACRO_NAME@ @DEFINE_EXPORT@ 13 | # else 14 | /* We are using this library */ 15 | # define @EXPORT_MACRO_NAME@ @DEFINE_IMPORT@ 16 | # endif 17 | # endif 18 | 19 | # ifndef @NO_EXPORT_MACRO_NAME@ 20 | # define @NO_EXPORT_MACRO_NAME@ @DEFINE_NO_EXPORT@ 21 | # endif 22 | #endif 23 | 24 | #ifndef @DEPRECATED_MACRO_NAME@ 25 | # define @DEPRECATED_MACRO_NAME@ @DEFINE_DEPRECATED@ 26 | #endif 27 | 28 | #ifndef @DEPRECATED_MACRO_NAME@_EXPORT 29 | # define @DEPRECATED_MACRO_NAME@_EXPORT @EXPORT_MACRO_NAME@ @DEPRECATED_MACRO_NAME@ 30 | #endif 31 | 32 | #ifndef @DEPRECATED_MACRO_NAME@_NO_EXPORT 33 | # define @DEPRECATED_MACRO_NAME@_NO_EXPORT @NO_EXPORT_MACRO_NAME@ @DEPRECATED_MACRO_NAME@ 34 | #endif 35 | 36 | #cmakedefine01 DEFINE_NO_DEPRECATED 37 | #if DEFINE_NO_DEPRECATED 38 | # define @NO_DEPRECATED_MACRO_NAME@ 39 | #endif 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /cmake_uninstall.cmake.in: -------------------------------------------------------------------------------- 1 | # Uninstall script for directory: @CMAKE_CURRENT_BINARY_DIR@ 2 | 3 | if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") 4 | message(FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") 5 | endif() 6 | 7 | file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) 8 | string(REPLACE "\n" ";" files "${files}") 9 | foreach(file ${files}) 10 | message(STATUS "Uninstalling: $ENV{DESTDIR}${file}") 11 | if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") 12 | execute_process( 13 | COMMAND "@CMAKE_COMMAND@" -E remove "$ENV{DESTDIR}${file}" 14 | RESULT_VARIABLE rm_retval 15 | OUTPUT_QUIET ERROR_QUIET 16 | ) 17 | if(NOT "${rm_retval}" STREQUAL 0) 18 | message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") 19 | endif() 20 | else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") 21 | message(STATUS "File $ENV{DESTDIR}${file} does not exist.") 22 | endif() 23 | endforeach() 24 | -------------------------------------------------------------------------------- /examples/hello/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2009-2015 Andrew Sutton 2 | # All rights reserved 3 | 4 | # Add an executable. 5 | add_executable(hello EXCLUDE_FROM_ALL hello.cpp) 6 | target_link_libraries(hello origin-core) 7 | -------------------------------------------------------------------------------- /examples/hello/hello.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | #include 7 | 8 | 9 | template 10 | void f(T const& t) 11 | { 12 | std::cout << t << '\n'; 13 | } 14 | 15 | 16 | int 17 | main() 18 | { 19 | f("Hello, world!"); 20 | } 21 | -------------------------------------------------------------------------------- /examples/origin.math/moving_means.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | int main() { 4 | std::vector values = {1, 2, 3, 4, 5, 6}; 5 | auto f = std::begin(values); 6 | auto l = std::end(values); 7 | for (auto x : origin::moving_means(f, f + 2, l)) { 8 | std::cout << x << std::endl; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /examples/origin.math/moving_sums: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asutton/origin/4358f0d1962e2ca9b925eeb8ff11ea501cf77ccb/examples/origin.math/moving_sums -------------------------------------------------------------------------------- /examples/origin.math/moving_sums.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() { 6 | std::vector values = {1, 2, 3, 4, 5, 6}; 7 | auto f = std::begin(values); 8 | auto l = std::end(values); 9 | std::vector result; 10 | origin::moving_sums(f, f + 2, l, std::back_inserter(result), 0.0); 11 | for (auto x : result) { 12 | std::cout << x << std::endl; 13 | } 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /origin.graph/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2009-2015 Andrew Sutton 2 | # All rights reserved 3 | 4 | include(GenerateExportHeader) 5 | 6 | # Set variables. 7 | 8 | # Add options. 9 | 10 | # Run platform checks. 11 | 12 | # Set compiler and linker flags. 13 | add_compiler_export_flags() 14 | 15 | # Add a library. 16 | add_library(origin-graph STATIC 17 | adjacency_list.cpp 18 | adjacency_vector.cpp) 19 | 20 | target_compile_options(origin-graph PUBLIC -std=c++1z -fconcepts) 21 | target_include_directories(origin-graph 22 | PUBLIC "$") 23 | target_link_libraries(origin-graph PUBLIC origin-core origin-range) 24 | 25 | add_dependencies(check origin-graph) 26 | 27 | # Generate the configuration header. 28 | configure_file(config.hpp.in config.hpp) 29 | 30 | # Generate the export header. 31 | generate_export_header(origin-graph EXPORT_FILE_NAME export.hpp) 32 | 33 | # Add subdirectories. 34 | add_subdirectory(handle.test) 35 | add_subdirectory(adjacency_list.test) 36 | 37 | # Add install targets. 38 | # install( 39 | # TARGETS origin-graph 40 | # EXPORT OriginTargets 41 | # RUNTIME DESTINATION ${INSTALL_BIN_DIR} 42 | # LIBRARY DESTINATION ${INSTALL_LIB_DIR} 43 | # ARCHIVE DESTINATION ${INSTALL_LIB_DIR} 44 | # INCLUDES DESTINATION ${INSTALL_INCLUDE_DIR} 45 | # ) 46 | -------------------------------------------------------------------------------- /origin.graph/adjacency_list.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include "adjacency_list.hpp" 5 | -------------------------------------------------------------------------------- /origin.graph/adjacency_list.test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2009-2015 Andrew Sutton 2 | # All rights reserved 3 | 4 | link_libraries(origin-graph) 5 | 6 | add_run_test(graph_adjlist_pool pool.cpp) 7 | -------------------------------------------------------------------------------- /origin.graph/adjacency_list.test/adjacency_list.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | #include "../graph.test/testing.hpp" 7 | 8 | using namespace std; 9 | using namespace origin; 10 | using namespace testing; 11 | 12 | // A little helper class to help trace initializations and data movements. 13 | struct X 14 | { 15 | static bool trace; 16 | 17 | X() { if (trace) cout << "default\n"; } 18 | X(X&&) { if (trace) cout << "move\n"; } 19 | X(const X&) { if (trace) cout << "copy\n"; } 20 | }; 21 | 22 | bool X::trace = false; 23 | 24 | void 25 | trace_insert() 26 | { 27 | using G = directed_adjacency_list; 28 | G g; 29 | X x; 30 | 31 | // Each insertion should require exactly one initialization of X. 32 | X::trace = true; 33 | g.add_vertex(); 34 | g.add_vertex(std::move(x)); 35 | g.add_vertex(x); 36 | X::trace = false; 37 | } 38 | 39 | int main() 40 | { 41 | trace_insert(); 42 | 43 | // TODO: Write tests for adding vertices and edges. Even though those 44 | // features are thoroughly exercised by the remove edge tests, it might 45 | // be nice to include them here. 46 | 47 | using G = undirected_adjacency_list; 48 | check_default_init(); 49 | check_add_vertices(); 50 | check_add_edges(); 51 | check_remove_specific_edge(); 52 | check_remove_first_simple_edge(); 53 | check_remove_first_multi_edge(); 54 | check_remove_multi_edge(); 55 | check_remove_vertex_edges(); 56 | check_remove_all_edges(); 57 | 58 | using D = directed_adjacency_list; 59 | check_default_init(); 60 | check_add_vertices(); 61 | check_add_edges(); 62 | check_remove_specific_edge(); 63 | check_remove_first_simple_edge(); 64 | check_remove_first_multi_edge(); 65 | check_remove_multi_edge(); 66 | check_remove_vertex_edges(); 67 | check_remove_all_edges(); 68 | } 69 | -------------------------------------------------------------------------------- /origin.graph/adjacency_list.test/pool.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | int main() { } 5 | 6 | #if 0 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | using namespace std; 14 | using namespace origin; 15 | using namespace origin::adjacency_list_impl; 16 | 17 | 18 | template 19 | struct hack_queue : Q 20 | { 21 | using Q::c; 22 | using Q::comp; 23 | }; 24 | 25 | template 26 | const hack_queue& 27 | hack(const Q& q) 28 | { 29 | return reinterpret_cast&>(q); 30 | } 31 | 32 | template 33 | void 34 | print_queue(const P& p) 35 | { 36 | using Hack = hack_queue; 37 | const Hack& q = hack(p.free()); 38 | 39 | cout << "free: "; 40 | for (const auto& x : q.c) 41 | cout << x << ' '; 42 | cout << '\n'; 43 | } 44 | 45 | template 46 | void 47 | print_pool(const P& p) 48 | { 49 | using Vec = typename P::list_type; 50 | const Vec& v = p.data(); 51 | 52 | cout << "pool: "; 53 | for (const auto& x : v) { 54 | if (x) 55 | cout << x.get() << ' '; 56 | else 57 | cout << 'X' << ' '; 58 | } 59 | cout << '\n'; 60 | } 61 | 62 | template 63 | void 64 | print_live(P&& p) 65 | { 66 | cout << "live: "; 67 | for (const auto& x : p) 68 | cout << x << ' '; 69 | cout << '\n'; 70 | } 71 | 72 | template 73 | void debug_pool(P&& p) 74 | { 75 | print_pool(p); 76 | print_queue(p); 77 | print_live(p); 78 | // print_live((const P&)p); 79 | cout << "-----\n"; 80 | } 81 | 82 | 83 | void check_node() 84 | { 85 | pool_node a; 86 | assert(!a); 87 | 88 | pool_node b(0, 0, 3); 89 | assert(b); 90 | assert(b.get() == 3); 91 | } 92 | 93 | void 94 | check_pool_insert_1() 95 | { 96 | pool p; 97 | assert(p.empty()); 98 | 99 | size_t n = p.insert(10); 100 | assert(p.size() == 1); 101 | assert(p[n] == 10); 102 | } 103 | 104 | void 105 | check_pool_insert_n() 106 | { 107 | pool p; 108 | vector ns; 109 | for (int i = 0; i < 10; ++i) 110 | ns.push_back(p.insert(i)); 111 | assert(p.size() == 10); 112 | for (int i = 0; i < 10; ++i) 113 | assert(p[ns[i]] == i); 114 | } 115 | 116 | void 117 | check_pool_erase() 118 | { 119 | pool p; 120 | for (int i = 0; i < 10; ++i) 121 | p.insert(i); 122 | debug_pool(p); 123 | 124 | p.erase(9); 125 | assert(p.size() == 9); 126 | debug_pool(p); 127 | 128 | p.erase(3); 129 | assert(p.size() == 8); 130 | debug_pool(p); 131 | 132 | p.erase(1); 133 | assert(p.size() == 7); 134 | debug_pool(p); 135 | 136 | p.erase(7); 137 | assert(p.size() == 6); 138 | debug_pool(p); 139 | } 140 | 141 | void 142 | check_pool_reuse() 143 | { 144 | // Create a pool with 10 values and then erase every other. 145 | pool p; 146 | for (int i = 0; i < 10; ++i) 147 | p.insert(i); 148 | for (int i = 0; i < 5; ++i) 149 | p.erase(2 * i); 150 | debug_pool(p); 151 | 152 | // Re-use the dead lists 153 | for (int i = 0; i < 5; ++i) 154 | p.insert(2 * i); 155 | debug_pool(p); 156 | 157 | // Add more stuff. 158 | for (int i = 0; i < 10; ++i) 159 | p.insert(10 + i); 160 | debug_pool(p); 161 | } 162 | 163 | // Erase elements left-to-right, and then re-build the list. 164 | void 165 | check_pool_yoyo_lr() 166 | { 167 | std::cout << "*** yoyo (lr) ***\n"; 168 | pool p; 169 | for (int i = 0; i < 10; ++i) 170 | p.insert(i); 171 | for (int i = 0; i < 10; ++i) 172 | p.erase(i); 173 | debug_pool(p); 174 | for (int i = 0; i < 10; ++i) 175 | p.insert(i); 176 | debug_pool(p); 177 | } 178 | 179 | void 180 | check_pool_yoyo_rl() 181 | { 182 | std::cout << "*** yoyo (rl) ***\n"; 183 | pool p; 184 | for (int i = 0; i < 10; ++i) 185 | p.insert(i); 186 | for (int i = 0; i < 10; ++i) 187 | p.erase(10 - i - 1); 188 | debug_pool(p); 189 | for (int i = 0; i < 10; ++i) 190 | p.insert(i); 191 | debug_pool(p); 192 | } 193 | 194 | 195 | int main() 196 | { 197 | check_node(); 198 | check_pool_insert_1(); 199 | check_pool_insert_n(); 200 | check_pool_erase(); 201 | check_pool_reuse(); 202 | check_pool_yoyo_lr(); 203 | check_pool_yoyo_rl(); 204 | } 205 | 206 | #endif 207 | -------------------------------------------------------------------------------- /origin.graph/adjacency_vector.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include "adjacency_vector.hpp" 5 | -------------------------------------------------------------------------------- /origin.graph/adjacency_vector.test/adjacency_vector.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include "../graph.test/testing.hpp" 10 | 11 | using namespace std; 12 | using namespace origin; 13 | using namespace testing; 14 | 15 | int main() 16 | { 17 | using G = undirected_adjacency_vector; 18 | check_default_init(); 19 | check_add_vertices(); 20 | check_add_edges(); 21 | 22 | using D = directed_adjacency_vector; 23 | check_default_init(); 24 | check_add_vertices(); 25 | check_add_edges(); 26 | } 27 | -------------------------------------------------------------------------------- /origin.graph/concepts.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #ifndef GRAPH_CONCEPTS_HPP 5 | #define GRAPH_CONCEPTS_HPP 6 | 7 | #include 8 | 9 | namespace origin 10 | { 11 | // TODO: Lots and lots of traits for graphs! 12 | 13 | namespace graph_impl 14 | { 15 | template 16 | class get_out_edges 17 | { 18 | template 19 | static auto check(const X& x, Y y) -> decltype(x.out_edges(y)); 20 | 21 | static subst_failure check(...); 22 | public: 23 | using type = decltype(check(std::declval(), std::declval())); 24 | }; 25 | 26 | template 27 | class get_in_edges 28 | { 29 | template 30 | static auto check(const X& x, Y y) -> decltype(x.in_edges(y)); 31 | 32 | static subst_failure check(...); 33 | public: 34 | using type = decltype(check(std::declval(), std::declval())); 35 | }; 36 | 37 | template 38 | class get_inc_edges 39 | { 40 | template 41 | static auto check(const X& x, Y y) -> decltype(x.edges(y)); 42 | 43 | static subst_failure check(...); 44 | public: 45 | using type = decltype(check(std::declval(), std::declval())); 46 | }; 47 | 48 | } // namsepace graph_impl 49 | 50 | 51 | // Returns true iff g.out_edges(v) is a valid expression. 52 | template 53 | constexpr bool Has_out_edges() 54 | { 55 | return Subst_succeeded::type>(); 56 | } 57 | 58 | // Returns true iff g.in_edges(v) is a valid expression. 59 | template 60 | constexpr bool Has_in_edges() 61 | { 62 | return Subst_succeeded::type>(); 63 | } 64 | 65 | // Returns true iff g.eges(v) is a valid expression. 66 | template 67 | constexpr bool Has_incident_edges() 68 | { 69 | return Subst_succeeded::type>(); 70 | } 71 | 72 | 73 | 74 | // ------------------------------------------------------------------------ // 75 | // [graph.types] 76 | // Graph Type Functions 77 | // 78 | // TODO: These should probably be made a little more robust -- make them 79 | // dependent on the type of dereferncing a vertex or edge iterator. 80 | 81 | template 82 | using Vertex = typename G::vertex; 83 | 84 | template 85 | using Edge = typename G::edge; 86 | 87 | 88 | 89 | 90 | 91 | // ------------------------------------------------------------------------ // 92 | // [graph.concepts] 93 | // Graph Concepts 94 | // 95 | // TODO: Obviously, finish writing these. 96 | 97 | // Returns true if G is a directed graph. 98 | template 99 | constexpr bool Directed_graph() 100 | { 101 | return Has_out_edges>() && Has_in_edges>(); 102 | } 103 | 104 | // Returns true if G is an undirected graph. 105 | template 106 | constexpr bool Undirected_graph() 107 | { 108 | return Has_incident_edges>(); 109 | } 110 | 111 | } // namespace origin 112 | 113 | #endif 114 | -------------------------------------------------------------------------------- /origin.graph/config.hpp.in: -------------------------------------------------------------------------------- 1 | /** 2 | * @file origin.graph/config.hpp 3 | * The configuration header for the Origin.Graph library. 4 | * 5 | * @date 2015 6 | * @version @ORIGIN_VERSION@ 7 | */ 8 | 9 | /* config.hpp. Generated from config.hpp.in by cmake. */ 10 | 11 | #ifndef ORIGIN_GRAPH_CONFIG_HPP 12 | #define ORIGIN_GRAPH_CONFIG_HPP 13 | 14 | /* Name of package. */ 15 | #define ORIGIN_PACKAGE "@ORIGIN_PACKAGE_NAME@" 16 | 17 | /* Define to the full name of this package. */ 18 | #define ORIGIN_PACKAGE_NAME "@ORIGIN_PACKAGE_NAME@" 19 | 20 | /* Define to the one symbol short name of this package. */ 21 | #define ORIGIN_PACKAGE_TARNAME "@ORIGIN_PACKAGE_TARNAME@" 22 | 23 | /* Define to the version of this package. */ 24 | #define ORIGIN_PACKAGE_VERSION "@ORIGIN_PACKAGE_VERSION@" 25 | 26 | /* Define to the full name and version of this package. */ 27 | #define ORIGIN_PACKAGE_STRING "@ORIGIN_PACKAGE_STRING@" 28 | 29 | /* Define to the address where bug reports for this package should be sent. */ 30 | #define ORIGIN_PACKAGE_BUGREPORT "@ORIGIN_PACKAGE_BUGREPORT@" 31 | 32 | /* Define to the home page for this package. */ 33 | #define ORIGIN_PACKAGE_URL "@ORIGIN_PACKAGE_URL@" 34 | 35 | /* The version number of the Origin libraries. */ 36 | #define ORIGIN_VERSION "@ORIGIN_VERSION@" 37 | 38 | /* The major version of the Origin libraries. */ 39 | #define ORIGIN_VERSION_MAJOR @ORIGIN_VERSION_MAJOR@ 40 | 41 | /* The minor version of the Origin libraries. */ 42 | #define ORIGIN_VERSION_MINOR @ORIGIN_VERSION_MINOR@ 43 | 44 | /* The patch version of the Origin libraries. */ 45 | #define ORIGIN_VERSION_PATCH @ORIGIN_VERSION_PATCH@ 46 | 47 | /* The tweak version of the Origin libraries. */ 48 | #define ORIGIN_VERSION_TWEAK @ORIGIN_VERSION_TWEAK@ 49 | 50 | #include 51 | 52 | #endif // ORIGIN_GRAPH_CONFIG_HPP 53 | -------------------------------------------------------------------------------- /origin.graph/graph.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #ifndef GRAPH_HPP 5 | #define GRAPH_HPP 6 | 7 | #include 8 | 9 | namespace origin 10 | { 11 | // ------------------------------------------------------------------------ // 12 | // [graph.generic] 13 | // Generic Graph Interface 14 | // 15 | // The generic graph interface is a set of types and operations defined 16 | // commonly for various graph data structures. 17 | 18 | 19 | // Returns a range over the vertices of a graph. 20 | template 21 | inline auto 22 | vertices(const G& g) -> decltype(g.vertices()) { return g.vertices(); } 23 | 24 | // Returns a range over the edges of a graph. 25 | template 26 | inline auto 27 | edges(const G& g) -> decltype(g.edges()) { return g.edges(); } 28 | 29 | // Returns the source vertex of an edge in g. 30 | template 31 | inline Vertex 32 | source(const G& g, Edge e) { return g.source(e); } 33 | 34 | // Returns the target vertex of an edge in g. 35 | template 36 | inline Vertex 37 | target(const G& g, Edge e) { return g.target(e); } 38 | 39 | // Returns true if v is an isolated vertex. An isolated vertex is one that 40 | // has no incident edges. 41 | template 42 | inline bool 43 | is_isolated(const G& g, Vertex v) { return g.degree(v) == 0; } 44 | 45 | // Returns true iff v is the source vertex of e. 46 | template 47 | inline bool 48 | is_source(const G& g, Edge e, Vertex v) { return source(g, e) == v; } 49 | 50 | // Returns true iff v is the target vertex of e. 51 | template 52 | inline bool 53 | is_target(const G& g, Edge e, Vertex v) { return target(g, e) == v; } 54 | 55 | // Returns true iff v is an endpoint (source or target) of e. 56 | template 57 | inline bool 58 | is_endpoint(const G& g, Edge e, Vertex v) 59 | { 60 | return is_source(g, e, v) || is_target(g, e, v); 61 | } 62 | 63 | template 64 | inline Requires(), bool> 65 | are_endpoints(const G& g, Edge e, Vertex u, Vertex v) 66 | { 67 | return is_source(g, e, u) && is_target(g, e, v); 68 | } 69 | 70 | template 71 | inline Requires(), bool> 72 | are_endpoints(const G& g, Edge e, Vertex u, Vertex v) 73 | { 74 | return (is_source(g, e, u) && is_target(g, e, v)) 75 | || (is_source(g, e, v) && is_target(g, e, u)); 76 | } 77 | 78 | // Returns true if e is a self loop. 79 | template 80 | inline bool 81 | is_loop(const G& g, Edge e) { return source(g, e) == target(g, e); } 82 | 83 | // Return the opposite endpoint of the edge e in v. If v is not an endpoint 84 | // of e, the result is undefined. 85 | template 86 | inline Vertex 87 | opposite(const G& g, Edge e, Vertex v) 88 | { 89 | assert(is_endpoint(g, e, v)); 90 | Vertex u = source(g, e); 91 | return u == v ? target(g, e) : u; 92 | } 93 | 94 | 95 | 96 | // ------------------------------------------------------------------------ // 97 | // [graph.pred] 98 | // Common Graph Predicates 99 | // 100 | // The following function objects are useful in a number of graph operations. 101 | // 102 | // has_target 103 | // has_source 104 | // 105 | 106 | // Returns true when an edge is is the same as some target vertex. 107 | template 108 | struct has_target 109 | { 110 | has_target(const G& g, Vertex v) 111 | : g(g), v(v) 112 | { } 113 | 114 | inline bool 115 | operator()(Edge e) const { return target(g, e) == v; } 116 | 117 | const G& g; 118 | Vertex v; 119 | }; 120 | 121 | // Returns true when an edge is is the same as some source vertex. 122 | template 123 | struct has_source 124 | { 125 | has_source(const G& g, Vertex v) 126 | : g(g), v(v) 127 | { } 128 | 129 | inline bool 130 | operator()(Edge e) const { return source(g, e) == v; } 131 | 132 | const G& g; 133 | Vertex v; 134 | }; 135 | 136 | // Returns true if an edge has an end equal to v. 137 | template 138 | struct has_endpoint 139 | { 140 | has_endpoint(const G& g, Vertex v) 141 | : g(g), v(v) 142 | { } 143 | 144 | inline bool 145 | operator()(Edge e) const 146 | { 147 | return source(g, e) == v || target(g, e) == v; 148 | } 149 | 150 | const G& g; 151 | Vertex v; 152 | }; 153 | 154 | // Returns true if an edge has endpoints equal to u and v (in that order). 155 | // If G is undirected, then 156 | template 157 | struct has_endpoints 158 | { 159 | has_endpoints(const G& g, Vertex u, Vertex v) 160 | : g(g), u(u), v(v) 161 | { } 162 | 163 | inline bool 164 | operator()(Edge e) const 165 | { 166 | return are_endpoints(g, e, u, v); 167 | } 168 | 169 | const G& g; 170 | Vertex u; 171 | Vertex v; 172 | }; 173 | 174 | // Returns true when an edge e is a loop on vertex v. 175 | template 176 | struct is_looped 177 | { 178 | is_looped(const G& g, Vertex v) 179 | : g(g), v(v) 180 | { } 181 | 182 | inline bool 183 | operator()(Edge e) const 184 | { 185 | return is_source(g, e, v) && is_target(g, e, v); 186 | } 187 | 188 | const G& g; 189 | Vertex v; 190 | }; 191 | 192 | } // namespace origin 193 | 194 | #endif 195 | -------------------------------------------------------------------------------- /origin.graph/handle.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #ifndef ORIGIN_GRAPH_HANDLE_HPP 5 | #define ORIGIN_GRAPH_HANDLE_HPP 6 | 7 | #include 8 | #include 9 | 10 | namespace origin { 11 | // ------------------------------------------------------------------------ // 12 | // [graph.handle] 13 | // Handle 14 | // 15 | // A handle is an ordinal value type used to represent an object in a data 16 | // structure. Handles are implicitly interoperable with unsigned intger 17 | // (size_t) values, and have the special property that unsigned -1 indicates 18 | // an invalid object. 19 | // 20 | // TODO: Disable arithmetic operations? 21 | struct handle 22 | { 23 | static constexpr std::size_t npos = -1; 24 | 25 | handle(std::size_t n = npos); 26 | 27 | // Boolean 28 | explicit operator bool() const; 29 | 30 | // Integral 31 | operator std::size_t() const { return value; } 32 | 33 | // Hashable 34 | std::size_t hash() const; 35 | 36 | std::size_t value; 37 | }; 38 | 39 | inline 40 | handle::handle(std::size_t n) : value(n) { } 41 | 42 | inline 43 | handle::operator bool() const { return value != npos; } 44 | 45 | inline std::size_t 46 | handle::hash() const { return std::hash{}(value); } 47 | 48 | // Equality 49 | inline bool 50 | operator==(handle a, handle b) { return a.value == b.value; } 51 | 52 | inline bool 53 | operator!=(handle a, handle b) { return !(a == b); } 54 | 55 | // Ordering 56 | inline bool 57 | operator<(handle a, handle b) 58 | { 59 | if (!a) 60 | return bool(b); 61 | else 62 | return b ? a.value < b.value : false; 63 | } 64 | 65 | inline bool 66 | operator>(handle a, handle b) { return b < a; } 67 | 68 | inline bool 69 | operator<=(handle a, handle b) { return !(b < a); } 70 | 71 | inline bool 72 | operator>=(handle a, handle b) { return !(a < b); } 73 | 74 | 75 | // ------------------------------------------------------------------------ // 76 | // [graph.vhandle] 77 | // Vertex Handle 78 | // 79 | // A vertex handle is a handle specifically for graph vertices. It is 80 | // the same as a normal handle in every way except its type. 81 | struct vertex_handle : handle 82 | { 83 | using handle::handle; 84 | }; 85 | 86 | 87 | // ------------------------------------------------------------------------ // 88 | // [graph.ehandle] 89 | // Edge Handle 90 | // 91 | // An edge hadndle is a handle specifically for graph edges that are uniquely 92 | // identified by a single number. This is an uncommon property for graph 93 | // data structures. More frequently, edge handles are source/target pairs 94 | // or source/target/edge triples. See simple_edge_handle and multi_edge_handle 95 | // for details. 96 | struct edge_handle : handle 97 | { 98 | using handle::handle; 99 | }; 100 | 101 | 102 | // ------------------------------------------------------------------------ // 103 | // Simple Edge Handle 104 | // 105 | // An edge handle is a source/target pair that uniquely identifies an edge. 106 | // 107 | // TODO: Implement edge_handle. 108 | 109 | 110 | 111 | // ------------------------------------------------------------------------ // 112 | // Multi-edge Handle 113 | // 114 | // A multi-edge handle is a triple, describing source and target handles, 115 | // along with an edge handle. The source and target handles are usual 116 | // vertex handles (i.e., indexes), but the edge component may vary based on 117 | // the graph implementation. It is most often an index. 118 | // 119 | // FIXME: What is E? 120 | template 121 | struct multi_edge_handle 122 | { 123 | using handle_type = E; 124 | 125 | multi_edge_handle(); 126 | multi_edge_handle(vertex_handle s, vertex_handle t, E e); 127 | 128 | vertex_handle source() const; 129 | vertex_handle target() const; 130 | handle_type edge() const; 131 | 132 | // Hashable 133 | std::size_t hash() const; 134 | 135 | std::tuple value; 136 | }; 137 | 138 | template 139 | multi_edge_handle::multi_edge_handle() 140 | : value(vertex_handle::npos, vertex_handle::npos, E{}) 141 | { } 142 | 143 | template 144 | multi_edge_handle::multi_edge_handle(vertex_handle s, vertex_handle t, E e) 145 | : value(s, t, e) 146 | { } 147 | 148 | template 149 | auto multi_edge_handle::source() const -> vertex_handle 150 | { 151 | return std::get<0>(value); 152 | } 153 | 154 | template 155 | auto multi_edge_handle::target() const -> vertex_handle 156 | { 157 | return std::get<1>(value); 158 | } 159 | 160 | template 161 | auto multi_edge_handle::edge() const -> handle_type 162 | { 163 | return std::get<2>(value); 164 | } 165 | 166 | template 167 | inline std::size_t 168 | multi_edge_handle::hash() const 169 | { 170 | // TODO: Stop using GCC internal functions for hashing. 171 | return std::_Hash_bytes(&value, sizeof(value), 0); 172 | } 173 | 174 | // Equality 175 | template 176 | inline bool 177 | operator==(const multi_edge_handle& a, const multi_edge_handle& b) 178 | { 179 | return a.value == b.value; 180 | } 181 | 182 | template 183 | inline bool 184 | operator!=(const multi_edge_handle& a, const multi_edge_handle& b) 185 | { 186 | return !(a == b); 187 | } 188 | 189 | // Ordering 190 | template 191 | inline bool 192 | operator<(const multi_edge_handle& a, const multi_edge_handle& b) 193 | { 194 | return a.value < b.value; 195 | } 196 | 197 | template 198 | inline bool 199 | operator>(const multi_edge_handle& a, const multi_edge_handle& b) 200 | { 201 | return b < a; 202 | } 203 | 204 | template 205 | inline bool 206 | operator<=(const multi_edge_handle& a, const multi_edge_handle& b) 207 | { 208 | return !(b < a); 209 | } 210 | 211 | template 212 | inline bool 213 | operator>=(const multi_edge_handle& a, const multi_edge_handle& b) 214 | { 215 | return !(a < b); 216 | } 217 | 218 | } // namespace origin 219 | 220 | 221 | // Natively support the standard hashing protocol for vertex handles. 222 | namespace std { 223 | template<> 224 | struct hash 225 | { 226 | std::size_t 227 | operator()(origin::vertex_handle x) const { return x.hash(); } 228 | }; 229 | 230 | template 231 | struct hash> 232 | { 233 | std::size_t 234 | operator()(const origin::multi_edge_handle& h) { return h.hash(); } 235 | }; 236 | } // namespace std 237 | 238 | 239 | #endif 240 | -------------------------------------------------------------------------------- /origin.graph/handle.test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2009-2015 Andrew Sutton 2 | # All rights reserved 3 | 4 | link_libraries(origin-graph) 5 | 6 | add_run_test(graph_handle handle.cpp) 7 | -------------------------------------------------------------------------------- /origin.graph/handle.test/handle.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | using namespace std; 11 | using namespace origin; 12 | 13 | template 14 | void check_eq() 15 | { 16 | H a; 17 | H b = 1; 18 | H c = b; 19 | assert(a == a); 20 | assert(a != b); 21 | assert(b == c); 22 | } 23 | 24 | template 25 | void check_ord() 26 | { 27 | H a; 28 | H b = 1; 29 | 30 | assert(a <= a); 31 | assert(a >= a); 32 | 33 | assert(a < b); 34 | assert(a <= b); 35 | 36 | assert(b > a); 37 | assert(b >= a); 38 | } 39 | 40 | 41 | template 42 | void check_interop() 43 | { 44 | vector v {3, 2, 1}; 45 | H h = 0; 46 | assert(v[h] == 3); 47 | } 48 | 49 | int f(int n) { return n; } 50 | 51 | // Check that conversion to integral types is unambigous and actually 52 | // converts to an integer and not bool. 53 | template 54 | void check_conv() 55 | { 56 | H a = 3; 57 | assert(f(a) == 3); 58 | } 59 | 60 | // Support for testing conversions. 61 | void fv(vertex_handle v) { } 62 | void fe(edge_handle e) { } 63 | 64 | int main() 65 | { 66 | check_eq(); 67 | check_ord(); 68 | check_interop(); 69 | 70 | check_eq(); 71 | check_ord(); 72 | check_interop(); 73 | 74 | 75 | // I don't know if this is good or not. 76 | handle a = 3; 77 | handle b = 1; 78 | assert(a + b == 4); 79 | 80 | vertex_handle v; 81 | fv(v); // OK 82 | // fe(v); // Error: cannot convert v to e 83 | 84 | edge_handle e; 85 | fe(e); // Ok 86 | // fv(e); // Error: cannot convert e to v 87 | 88 | // FIXME: This should not work. 89 | assert(v == e); 90 | } 91 | -------------------------------------------------------------------------------- /origin.graph/io.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #ifndef ORIGIN_GRAPH_IO_HPP 5 | #define ORIGIN_GRAPH_IO_HPP 6 | 7 | #include 8 | 9 | #include 10 | 11 | namespace origin 12 | { 13 | namespace io 14 | { 15 | // ---------------------------------------------------------------------- // 16 | // [graph.io] 17 | // Graph I/O 18 | // 19 | // Support for various forms of graph I/O. 20 | // 21 | // TODO: Rewrite the operations used by this module in terms of the generic 22 | // graph interface. 23 | // 24 | // TODO: Develop type constraints for these operations. Also, what should 25 | // we print when no value types have been given. 26 | 27 | 28 | // Support the printing of vertex lists. 29 | template 30 | struct vertex_list_printer 31 | { 32 | vertex_list_printer(const G& g) : g(g) { } 33 | const G& g; 34 | }; 35 | 36 | // Returns a vertex list. 37 | template 38 | inline vertex_list_printer 39 | vertex_list(const G& g) { return vertex_list_printer(g); } 40 | 41 | 42 | // Support the printing of edge lists. 43 | template 44 | struct edge_list_printer 45 | { 46 | edge_list_printer(const G& g) : g(g) { } 47 | const G& g; 48 | }; 49 | 50 | // Return an edge list printer. 51 | template 52 | inline edge_list_printer 53 | edge_list(const G& g) { return edge_list_printer(g); } 54 | 55 | 56 | // Supports the printing of edge tuples. 57 | template 58 | struct edge_printer 59 | { 60 | edge_printer(const G& g, Edge e) : g(g), e(e) { } 61 | const G& g; 62 | Edge e; 63 | }; 64 | 65 | // Returns an edge printer. 66 | template 67 | inline edge_printer 68 | edge(const G& g, Edge e) { return edge_printer(g, e); } 69 | 70 | 71 | // Print the vertex list of a graph. Each vertex is printed on a 72 | // separate line. 73 | template 74 | inline std::basic_ostream& 75 | operator<<(std::basic_ostream& os, vertex_list_printer p) 76 | { 77 | const G& g = p.g; 78 | for (auto v : g.vertices()) 79 | os << g(v) << '\n'; 80 | return os; 81 | } 82 | 83 | // Print the edge list of a graph. 84 | template 85 | inline std::basic_ostream& 86 | operator<<(std::basic_ostream& os, edge_list_printer p) 87 | { 88 | const G& g = p.g; 89 | for (auto e : g.edges()) 90 | os << edge(g, e) << '\n'; 91 | return os; 92 | } 93 | 94 | template 95 | inline std::basic_ostream& 96 | operator<<(std::basic_ostream& os, edge_printer p) 97 | { 98 | const G& g = p.g; 99 | Edge e = p.e; 100 | Vertex u = g.source(e); 101 | Vertex v = g.target(e); 102 | return os << g(u) << ' ' << g(v) << ' ' << g(e); 103 | } 104 | 105 | } // namespace io 106 | } // namespace origin 107 | 108 | #endif 109 | -------------------------------------------------------------------------------- /origin.math/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2009-2015 Andrew Sutton 2 | # All rights reserved 3 | 4 | include(GenerateExportHeader) 5 | 6 | # Set variables. 7 | 8 | # Add options. 9 | 10 | # Run platform checks. 11 | 12 | # Set compiler and linker flags. 13 | add_compiler_export_flags() 14 | 15 | # Add a library. 16 | add_library(origin-math STATIC 17 | numeric.cpp 18 | stats.cpp) 19 | 20 | target_compile_options(origin-math PUBLIC -std=c++1z -fconcepts) 21 | target_include_directories(origin-math 22 | PUBLIC "$") 23 | 24 | add_dependencies(check origin-math) 25 | 26 | # Generate the configuration header. 27 | configure_file(config.hpp.in config.hpp) 28 | 29 | # Generate the export header. 30 | generate_export_header(origin-math EXPORT_FILE_NAME export.hpp) 31 | 32 | # Add subdirectories. 33 | 34 | # Add install targets. 35 | # install( 36 | # TARGETS origin-math 37 | # EXPORT OriginTargets 38 | # RUNTIME DESTINATION ${INSTALL_BIN_DIR} 39 | # LIBRARY DESTINATION ${INSTALL_LIB_DIR} 40 | # ARCHIVE DESTINATION ${INSTALL_LIB_DIR} 41 | # INCLUDES DESTINATION ${INSTALL_INCLUDE_DIR} 42 | # ) 43 | -------------------------------------------------------------------------------- /origin.math/config.hpp.in: -------------------------------------------------------------------------------- 1 | /** 2 | * @file origin.math/config.hpp 3 | * The configuration header for the Origin.Math library. 4 | * 5 | * @date 2015 6 | * @version @ORIGIN_VERSION@ 7 | */ 8 | 9 | /* config.hpp. Generated from config.hpp.in by cmake. */ 10 | 11 | #ifndef ORIGIN_MATH_CONFIG_HPP 12 | #define ORIGIN_MATH_CONFIG_HPP 13 | 14 | /* Name of package. */ 15 | #define ORIGIN_PACKAGE "@ORIGIN_PACKAGE_NAME@" 16 | 17 | /* Define to the full name of this package. */ 18 | #define ORIGIN_PACKAGE_NAME "@ORIGIN_PACKAGE_NAME@" 19 | 20 | /* Define to the one symbol short name of this package. */ 21 | #define ORIGIN_PACKAGE_TARNAME "@ORIGIN_PACKAGE_TARNAME@" 22 | 23 | /* Define to the version of this package. */ 24 | #define ORIGIN_PACKAGE_VERSION "@ORIGIN_PACKAGE_VERSION@" 25 | 26 | /* Define to the full name and version of this package. */ 27 | #define ORIGIN_PACKAGE_STRING "@ORIGIN_PACKAGE_STRING@" 28 | 29 | /* Define to the address where bug reports for this package should be sent. */ 30 | #define ORIGIN_PACKAGE_BUGREPORT "@ORIGIN_PACKAGE_BUGREPORT@" 31 | 32 | /* Define to the home page for this package. */ 33 | #define ORIGIN_PACKAGE_URL "@ORIGIN_PACKAGE_URL@" 34 | 35 | /* The version number of the Origin libraries. */ 36 | #define ORIGIN_VERSION "@ORIGIN_VERSION@" 37 | 38 | /* The major version of the Origin libraries. */ 39 | #define ORIGIN_VERSION_MAJOR @ORIGIN_VERSION_MAJOR@ 40 | 41 | /* The minor version of the Origin libraries. */ 42 | #define ORIGIN_VERSION_MINOR @ORIGIN_VERSION_MINOR@ 43 | 44 | /* The patch version of the Origin libraries. */ 45 | #define ORIGIN_VERSION_PATCH @ORIGIN_VERSION_PATCH@ 46 | 47 | /* The tweak version of the Origin libraries. */ 48 | #define ORIGIN_VERSION_TWEAK @ORIGIN_VERSION_TWEAK@ 49 | 50 | #include 51 | 52 | #endif // ORIGIN_MATH_CONFIG_HPP 53 | -------------------------------------------------------------------------------- /origin.math/numeric.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | -------------------------------------------------------------------------------- /origin.math/numeric.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #ifndef ORIGIN_MATH_NUMERIC_HPP 5 | #define ORIGIN_MATH_NUMERIC_HPP 6 | 7 | // #include 8 | // #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | // The numeric module provides basic algorithms for operations on numeric 16 | // types. Note the term "numeric" generally applies to any type for which 17 | // an algebraic structure can be defined. For example, strings are not 18 | // generally considered numeric quantities, yet they naturally form a 19 | // monoid under concatenation. 20 | // 21 | // TODO: The definition of identity elements is not easily solved for 22 | // numeric types. In some cases, the identity element may be patterened 23 | // on some other element in a sequence. For example, the additive idenity 24 | // of a vector in Rn, where n is a runtime quantity, is the vector with n 25 | // 0.0 values. 26 | // 27 | // Currently, we assume that for some numeric type T, T{0} constructs the 28 | // additive identity and T{1} constructs the multiplicative identity. 29 | 30 | namespace origin { 31 | 32 | // FIXME: Do not define this: 33 | 34 | template 35 | using Value_type = typename T::value_type; 36 | 37 | 38 | // -------------------------------------------------------------------------- // 39 | // Numeric values [num.values] 40 | 41 | // Returns true if the Integral value n is even. 42 | template 43 | inline bool even(T n) { return n % 2 == 0; } 44 | 45 | // Returns true if the Integral value n is odd. 46 | template 47 | inline bool odd(T n) { return n % 2 == 1; } 48 | 49 | // Returns true if n is an infinite value. Note that n could be positive 50 | // or negative infinity. 51 | // 52 | // TODO: This is not general. 53 | template 54 | inline bool 55 | is_infinity(T n) { return std::isinf(n); } 56 | 57 | 58 | // -------------------------------------------------------------------------- // 59 | // Accumulation [num.accumulate] 60 | 61 | // Returns the accumulation of the elements in [first, last), with 62 | // value as the initial element in the accumulation, using the 63 | // binary operator op to combine consecutive elemens in the range. 64 | template 65 | inline T 66 | accumulate(I first, I last, T value, Op op) { 67 | while (first != last) { 68 | value = op(value, *first); 69 | ++first; 70 | } 71 | return value; 72 | } 73 | 74 | // Returns the sum of the elements in [first, last), with value 75 | // as the initial element in the accumulation. 76 | template 77 | inline T 78 | accumulate(I first, I last, T value) { 79 | return accumulate(first, last, value, std::plus{}); 80 | } 81 | 82 | // Return the sum of elements in the range [first, last). 83 | template> 84 | inline T 85 | sum(I first, I last) { 86 | return accumulate(first, last, T{0}, std::plus{}); 87 | } 88 | 89 | // Return the product of the elements in the range [first, last). 90 | template> 91 | inline T 92 | product(I first, I last) { 93 | return accumulate(first, last, T{1}, std::multiplies{}); 94 | } 95 | 96 | } // namespace origin 97 | 98 | #endif 99 | -------------------------------------------------------------------------------- /origin.math/stats.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | -------------------------------------------------------------------------------- /origin/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2009-2015 Andrew Sutton 2 | # All rights reserved 3 | 4 | # Add subdirectories. 5 | add_subdirectory(core) 6 | add_subdirectory(memory) 7 | add_subdirectory(iterator) 8 | add_subdirectory(range) 9 | add_subdirectory(algorithm) 10 | add_subdirectory(data) 11 | # add_subdirectory(numeric) 12 | 13 | # Add a library. 14 | add_library(origin origin.cpp) 15 | target_link_libraries(origin PUBLIC 16 | origin-core 17 | origin-memory 18 | origin-iterator 19 | origin-range 20 | origin-algorithm 21 | origin-data) 22 | -------------------------------------------------------------------------------- /origin/algorithm.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #ifndef ORIGIN_ALGORITHM_HPP 5 | #define ORIGIN_ALGORITHM_HPP 6 | 7 | // Non-modifying predicate/equality algorithms 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | // Mutating algorithms. 15 | #include 16 | 17 | // Order-based algorithms 18 | 19 | // Memory algorithms 20 | #include 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /origin/algorithm/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2009-2015 Andrew Sutton 2 | # All rights reserved 3 | 4 | include(GenerateExportHeader) 5 | 6 | # Set variables. 7 | 8 | # Add options. 9 | 10 | # Run platform checks. 11 | 12 | # Set compiler and linker flags. 13 | add_compiler_export_flags() 14 | 15 | # Add a library. 16 | add_library(origin-algorithm STATIC 17 | concepts.cpp 18 | copy.cpp 19 | count.cpp 20 | equal.cpp 21 | find.cpp 22 | foreach.cpp 23 | quantifier.cpp 24 | uninitialized.cpp) 25 | 26 | target_compile_options(origin-algorithm PUBLIC -std=c++1z -fconcepts) 27 | target_include_directories(origin-algorithm 28 | PUBLIC "$") 29 | target_link_libraries(origin-algorithm 30 | PUBLIC origin-core origin-iterator origin-memory origin-range) 31 | 32 | add_dependencies(check origin-algorithm) 33 | 34 | # Generate the configuration header. 35 | configure_file(config.hpp.in config.hpp) 36 | 37 | # Generate the export header. 38 | generate_export_header(origin-algorithm EXPORT_FILE_NAME export.hpp) 39 | 40 | # Add subdirectories. 41 | add_subdirectory(algorithm.test) 42 | 43 | # Add install targets. 44 | install( 45 | TARGETS origin-algorithm 46 | EXPORT OriginTargets 47 | RUNTIME DESTINATION ${INSTALL_BIN_DIR} 48 | LIBRARY DESTINATION ${INSTALL_LIB_DIR} 49 | ARCHIVE DESTINATION ${INSTALL_LIB_DIR} 50 | INCLUDES DESTINATION ${INSTALL_INCLUDE_DIR} 51 | ) 52 | -------------------------------------------------------------------------------- /origin/algorithm/algorithm.test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2009-2015 Andrew Sutton 2 | # All rights reserved 3 | 4 | link_libraries(origin-algorithm) 5 | 6 | add_run_test(range_algo_for_each for_each.cpp) 7 | 8 | add_run_test(range_algo_all_of all_of.cpp) 9 | add_run_test(range_algo_any_of any_of.cpp) 10 | add_run_test(range_algo_none_of none_of.cpp) 11 | add_run_test(range_algo_count_if count_if.cpp) 12 | 13 | # add_run_test(range_algo_find find.cpp) 14 | # add_run_test(range_algo_find_if find_if.cpp) 15 | # add_run_test(range_algo_find_if_not find_if_not.cpp) 16 | 17 | # add_run_test(range_algo_count count.cpp) 18 | # add_run_test(range_algo_adjacent_find adjacent_find.cpp) 19 | # add_run_test(range_algo_mismatch mismatch.cpp) 20 | # add_run_test(range_algo_equal equal.cpp) 21 | # add_run_test(range_algo_find_first_of find_first_of.cpp) 22 | # add_run_test(range_algo_find_end find_end.cpp) 23 | 24 | add_run_test(seq_algo_copy copy.cpp) 25 | -------------------------------------------------------------------------------- /origin/algorithm/algorithm.test/adjacent_find.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | 10 | int main() 11 | { 12 | int a1[3] { 1, 1, 2 }; 13 | assert(origin::adjacent_find(a1) == a1); 14 | 15 | int a2[3] { 1, 1, 2 }; 16 | assert(origin::adjacent_find(a2, std::equal_to{}) == a2); 17 | } 18 | -------------------------------------------------------------------------------- /origin/algorithm/algorithm.test/all_of.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | #include 7 | 8 | 9 | bool pos(int n) { return n > 0; } 10 | 11 | 12 | int main() 13 | { 14 | int a[3] { 1, 2, 3 }; 15 | assert(origin::all_of(a, a + 3, pos)); 16 | // assert(origin::all_of(a, pos)); 17 | // assert(origin::all_of({1, 2, 3}, pos)); 18 | } 19 | -------------------------------------------------------------------------------- /origin/algorithm/algorithm.test/any_of.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | #include 7 | 8 | 9 | bool pos(int n) { return n > 0; } 10 | 11 | int main() 12 | { 13 | int a[3] { 1, 2, 3 }; 14 | assert(origin::any_of(a, a + 3, pos)); 15 | assert(origin::any_of(a, pos)); 16 | assert(origin::any_of({1, 2, 3}, pos)); 17 | } 18 | -------------------------------------------------------------------------------- /origin/algorithm/algorithm.test/copy.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | 11 | int main() 12 | { 13 | int a1[3] { 1, 1, 2 }; 14 | 15 | std::vector v1(3); 16 | origin::copy(a1, a1 + 3, v1.begin()); 17 | assert(std::equal(a1, a1 + 3, v1.begin())); 18 | 19 | std::vector v2(3); 20 | origin::copy(a1, v2); 21 | assert(std::equal(a1, a1 + 3, v2.begin())); 22 | } 23 | -------------------------------------------------------------------------------- /origin/algorithm/algorithm.test/count.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | 10 | int main() 11 | { 12 | int a[3] { 1, 2, 3 }; 13 | assert(origin::count(a, 1) == 1); 14 | 15 | std::vector v { 1, 2, 3 }; 16 | assert(origin::count(v, 1) == 1); 17 | 18 | const std::vector& cv = v; 19 | assert(origin::count(cv, 1) == 1); 20 | } 21 | -------------------------------------------------------------------------------- /origin/algorithm/algorithm.test/count_if.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | #include 7 | 8 | 9 | bool pos(int n) { return n > 0; } 10 | 11 | int main() 12 | { 13 | int a[3] { 1, 2, 3 }; 14 | assert(origin::count_if(a, a + 3, pos, 0) == 3); 15 | assert(origin::count_if(a, a + 3, pos) == 3); 16 | assert(origin::count_if(a, pos, 0) == 3); 17 | assert(origin::count_if(a, pos) == 3); 18 | assert(origin::count_if({1, 2, 3}, pos, 0) == 3); 19 | assert(origin::count_if({1, 2, 3}, pos) == 3); 20 | } 21 | -------------------------------------------------------------------------------- /origin/algorithm/algorithm.test/equal.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | 10 | int main() 11 | { 12 | int a1[3] { 1, 1, 2 }; 13 | int a2[3] { 1, 1, 2 }; 14 | origin::equal_to eq; 15 | assert(origin::equal(a1, a2)); 16 | assert(origin::equal(a1, a2, eq)); 17 | } 18 | -------------------------------------------------------------------------------- /origin/algorithm/algorithm.test/find.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | 10 | int main() 11 | { 12 | int a[3] { 1, 2, 3 }; 13 | assert(origin::find(a, 1) == a); 14 | 15 | std::vector v { 1, 2, 3 }; 16 | assert(origin::find(v, 1) == v.begin()); 17 | 18 | const std::vector& cv = v; 19 | assert(origin::find(cv, 1) == v.begin()); 20 | } 21 | -------------------------------------------------------------------------------- /origin/algorithm/algorithm.test/find_end.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | 10 | int main() 11 | { 12 | int a1[3] { 1, 1, 2 }; 13 | int a2[2] { 1, 1 }; 14 | origin::equal_to eq; 15 | assert(origin::find_end(a1, a2) == a1); 16 | assert(origin::find_end(a1, a2, eq) == a1); 17 | } 18 | -------------------------------------------------------------------------------- /origin/algorithm/algorithm.test/find_first_of.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | 10 | int main() 11 | { 12 | int a1[3] { 1, 1, 2 }; 13 | int a2[3] { 1, 1 }; 14 | std::equal_to eq; 15 | assert(origin::find_first_of(a1, a2) == a1); 16 | assert(origin::find_first_of(a1, a2, eq) == a1); 17 | } 18 | -------------------------------------------------------------------------------- /origin/algorithm/algorithm.test/find_if.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | 10 | bool pos(int n) { return n > 0; } 11 | 12 | int main() 13 | { 14 | int a[3] { 1, 2, 3 }; 15 | assert(origin::find_if(a, pos) == a); 16 | 17 | std::vector v { 1, 2, 3 }; 18 | assert(origin::find_if(v, pos) == v.begin()); 19 | 20 | const std::vector& cv = v; 21 | assert(origin::find_if(cv, pos) == cv.begin()); 22 | } 23 | -------------------------------------------------------------------------------- /origin/algorithm/algorithm.test/find_if_not.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | 10 | bool pos(int n) { return n > 0; } 11 | 12 | int main() 13 | { 14 | int a[3] { 1, 2, 3 }; 15 | assert(origin::find_if_not(a, pos) == a + 3); 16 | 17 | std::vector v { 1, 2, 3 }; 18 | assert(origin::find_if_not(v, pos) == v.end()); 19 | 20 | const std::vector& cv = v; 21 | assert(origin::find_if_not(cv, pos) == cv.end()); 22 | } 23 | -------------------------------------------------------------------------------- /origin/algorithm/algorithm.test/for_each.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | 11 | struct trip_count 12 | { 13 | trip_count() : n(0) { } 14 | 15 | template 16 | void operator()(const T&) { ++n; } 17 | 18 | int n = 0; 19 | }; 20 | 21 | 22 | struct S 23 | { 24 | void f() { ++x; } 25 | int x = 0; 26 | }; 27 | 28 | 29 | int main() 30 | { 31 | int a[3] { 1, 2, 3 }; 32 | 33 | // std::cout << origin::for_each(a, a + 3, trip_count{}).n << '\n'; 34 | 35 | assert(origin::for_each(a, a + 3, trip_count{}).n == 3); 36 | assert(origin::for_each(a, trip_count{}).n == 3); 37 | assert(origin::for_each({1, 2, 3}, trip_count{}).n == 3); 38 | 39 | S s[3]; 40 | origin::for_each(s, s + 3, &S::f); 41 | origin::for_each(s, &S::f); 42 | assert(s[0].x == 2 and s[1].x == 2 and s[2].x == 2); 43 | } 44 | -------------------------------------------------------------------------------- /origin/algorithm/algorithm.test/mismatch.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | int a1[3] { 1, 1, 2 }; 12 | int a2[3] { 2, 1, 2 }; 13 | std::equal_to eq; 14 | assert(origin::mismatch(a1, a2) == std::make_pair(a1, a2)); 15 | assert(origin::mismatch(a1, a2, eq) == std::make_pair(a1, a2)); 16 | } 17 | -------------------------------------------------------------------------------- /origin/algorithm/algorithm.test/none_of.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | #include 7 | 8 | bool pos(int n) { return n > 0; } 9 | 10 | int main() 11 | { 12 | int a[3] { 1, 2, 3 }; 13 | assert(origin::none_of(a, a + 3, pos)); 14 | assert(origin::none_of(a, pos)); 15 | assert(origin::none_of({1, 2, 3}, pos)); 16 | } 17 | -------------------------------------------------------------------------------- /origin/algorithm/concepts.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include "concepts.hpp" 5 | -------------------------------------------------------------------------------- /origin/algorithm/concepts.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #ifndef ORIGIN_ALGORITHM_CONCEPTS_HPP 5 | #define ORIGIN_ALGORITHM_CONCEPTS_HPP 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | 13 | namespace origin 14 | { 15 | 16 | // -------------------------------------------------------------------------- // 17 | // Algorithm Concepts [algo.concepts] // 18 | 19 | // Indirectly_movable 20 | template 21 | concept bool 22 | Indirectly_movable() 23 | { 24 | return Input_iterator() && Output_iterator&&>(); 25 | } 26 | 27 | 28 | // Indirectly_copyable 29 | template 30 | concept bool 31 | Indirectly_copyable() 32 | { 33 | return Indirectly_movable() && Output_iterator>(); 34 | } 35 | 36 | 37 | // Indirectly_swappable 38 | template 39 | concept bool 40 | Indirectly_swappable() 41 | { 42 | return Indirectly_movable() 43 | && Indirectly_movable() 44 | && Movable>() 45 | && Movable>(); 46 | } 47 | 48 | 49 | // Indirectly_equal 50 | template 51 | concept bool 52 | Indirectly_equal() 53 | { 54 | return Input_iterator() 55 | && Input_iterator() 56 | && Equality_comparable, Value_type>(); 57 | } 58 | 59 | 60 | // Indirectly_ordered 61 | template 62 | concept bool 63 | Indirectly_ordered() 64 | { 65 | return Input_iterator() 66 | && Input_iterator() 67 | && Weakly_ordered, Value_type>(); 68 | } 69 | 70 | 71 | // Indirectly_comparable 72 | template 73 | concept bool 74 | Indirectly_comparable() 75 | { 76 | return Input_iterator() 77 | && Input_iterator() 78 | && Relation, Value_type>(); 79 | } 80 | 81 | 82 | // Iter_query 83 | template 84 | concept bool 85 | Iterator_query() 86 | { 87 | return Input_iterator() && Predicate>(); 88 | } 89 | 90 | 91 | // Range_query 92 | template 93 | concept bool 94 | Range_query() 95 | { 96 | return Range() && Iterator_query, P>(); 97 | } 98 | 99 | 100 | // Iter_search 101 | template 102 | concept bool 103 | Iterator_search() 104 | { 105 | return Input_iterator() && Equality_comparable, T>(); 106 | } 107 | 108 | 109 | // Range_search 110 | template 111 | concept bool 112 | Range_search() 113 | { 114 | return Range() && Iterator_search, T>(); 115 | } 116 | 117 | 118 | // Indirectly_range_equal 119 | template 120 | concept bool 121 | Indirectly_range_equal() 122 | { 123 | return Range() 124 | && Range() 125 | && Indirectly_equal, Iterator_type>(); 126 | } 127 | 128 | 129 | // Indirectly_range_comparable 130 | template 131 | concept bool 132 | Indirectly_range_comparable() 133 | { 134 | return Range() 135 | && Range() 136 | && Indirectly_comparable, Iterator_type, C>(); 137 | } 138 | 139 | 140 | } // namespace origin 141 | 142 | 143 | #endif 144 | -------------------------------------------------------------------------------- /origin/algorithm/config.hpp.in: -------------------------------------------------------------------------------- 1 | /** 2 | * @file origin/algorithm/config.hpp 3 | * The configuration header for the Origin.Algorithm library. 4 | * 5 | * @date 2015 6 | * @version @ORIGIN_VERSION@ 7 | */ 8 | 9 | /* config.hpp. Generated from config.hpp.in by cmake. */ 10 | 11 | #ifndef ORIGIN_ALGORITHM_CONFIG_HPP 12 | #define ORIGIN_ALGORITHM_CONFIG_HPP 13 | 14 | /* Name of package. */ 15 | #define ORIGIN_PACKAGE "@ORIGIN_PACKAGE_NAME@" 16 | 17 | /* Define to the full name of this package. */ 18 | #define ORIGIN_PACKAGE_NAME "@ORIGIN_PACKAGE_NAME@" 19 | 20 | /* Define to the one symbol short name of this package. */ 21 | #define ORIGIN_PACKAGE_TARNAME "@ORIGIN_PACKAGE_TARNAME@" 22 | 23 | /* Define to the version of this package. */ 24 | #define ORIGIN_PACKAGE_VERSION "@ORIGIN_PACKAGE_VERSION@" 25 | 26 | /* Define to the full name and version of this package. */ 27 | #define ORIGIN_PACKAGE_STRING "@ORIGIN_PACKAGE_STRING@" 28 | 29 | /* Define to the address where bug reports for this package should be sent. */ 30 | #define ORIGIN_PACKAGE_BUGREPORT "@ORIGIN_PACKAGE_BUGREPORT@" 31 | 32 | /* Define to the home page for this package. */ 33 | #define ORIGIN_PACKAGE_URL "@ORIGIN_PACKAGE_URL@" 34 | 35 | /* The version number of the Origin libraries. */ 36 | #define ORIGIN_VERSION "@ORIGIN_VERSION@" 37 | 38 | /* The major version of the Origin libraries. */ 39 | #define ORIGIN_VERSION_MAJOR @ORIGIN_VERSION_MAJOR@ 40 | 41 | /* The minor version of the Origin libraries. */ 42 | #define ORIGIN_VERSION_MINOR @ORIGIN_VERSION_MINOR@ 43 | 44 | /* The patch version of the Origin libraries. */ 45 | #define ORIGIN_VERSION_PATCH @ORIGIN_VERSION_PATCH@ 46 | 47 | /* The tweak version of the Origin libraries. */ 48 | #define ORIGIN_VERSION_TWEAK @ORIGIN_VERSION_TWEAK@ 49 | 50 | #include 51 | 52 | #endif // ORIGIN_ALGORITHM_CONFIG_HPP 53 | -------------------------------------------------------------------------------- /origin/algorithm/copy.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include "copy.hpp" 5 | -------------------------------------------------------------------------------- /origin/algorithm/copy.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #ifndef ORIGIN_ALGORITHM_COPY_HPP 5 | #define ORIGIN_ALGORITHM_COPY_HPP 6 | 7 | #include 8 | 9 | #include 10 | 11 | 12 | namespace origin 13 | { 14 | 15 | template> O> 16 | O 17 | copy(I first, I last, O out) 18 | { 19 | while (first != last) { 20 | *out = *first; 21 | ++first; 22 | ++out; 23 | } 24 | return out; 25 | } 26 | 27 | 28 | template> R2> 29 | Iterator_type 30 | copy(R1&& in, R2&& out) 31 | { 32 | using std::begin; 33 | using std::end; 34 | return copy(begin(in), end(in), begin(out)); 35 | } 36 | 37 | 38 | } // namesapce origin 39 | 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /origin/algorithm/count.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include "count.hpp" 5 | -------------------------------------------------------------------------------- /origin/algorithm/count.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #ifndef ORIGIN_ALGORITHM_COUNT_HPP 5 | #define ORIGIN_ALGORITHM_COUNT_HPP 6 | 7 | #include 8 | 9 | #include 10 | 11 | 12 | namespace origin 13 | { 14 | 15 | // -------------------------------------------------------------------------- // 16 | // Count If [algo.count_if] // 17 | // 18 | // count_if(first, last, pred, init) 19 | // count_if(first, last, pred) 20 | // count_if(range, pred, init) 21 | // count_if(range, pred) 22 | // 23 | // NOTE: The set of operations is extnded from those in the standard by 24 | // allowing an initial value (required only to be Advanceable) to be 25 | // provided. When not provided, the count starts from 0. 26 | 27 | template 28 | requires Sentinel() and Invokable_predicate>() 29 | inline Difference_type 30 | count_if(I first, S last, P pred, J value) 31 | { 32 | auto&& p = make_invokable(pred); 33 | while (first != last) { 34 | if (p(*first)) ++value; 35 | ++first; 36 | } 37 | return value; 38 | } 39 | 40 | 41 | template 42 | requires Sentinel() and Invokable_predicate>() 43 | inline Difference_type 44 | count_if(I first, S last, P pred) 45 | { 46 | using J = Difference_type; 47 | return origin::count_if(first, last, pred, J{0}); 48 | } 49 | 50 | 51 | template 52 | requires Invokable_predicate>() 53 | inline Size_type 54 | count_if(R&& range, P pred, J value) 55 | { 56 | return origin::count_if(std::begin(range), std::end(range), pred, value); 57 | } 58 | 59 | 60 | template 61 | requires Invokable_predicate>() 62 | inline Size_type 63 | count_if(R&& range, P pred) 64 | { 65 | using J = Size_type; 66 | return origin::count_if(std::begin(range), std::end(range), pred, J{0}); 67 | } 68 | 69 | 70 | template 71 | requires Invokable_predicate() 72 | inline std::size_t 73 | count_if(std::initializer_list list, P pred, J value) 74 | { 75 | return origin::count_if(list.begin(), list.end(), pred, value); 76 | } 77 | 78 | 79 | template 80 | requires Invokable_predicate() 81 | inline std::size_t 82 | count_if(std::initializer_list list, P pred) 83 | { 84 | return origin::count_if(list.begin(), list.end(), pred, std::size_t{0}); 85 | } 86 | 87 | 88 | // -------------------------------------------------------------------------- // 89 | // Count If Not [algo.count_if_not] // 90 | // 91 | // count_if_not(first, last, pred, init) 92 | // count_if_not(first, last, pred) 93 | // count_if_not(range, pred, init) 94 | // count_if_not(range, pred) 95 | 96 | 97 | template 98 | requires Sentinel() and Invokable_predicate>() 99 | inline Difference_type 100 | count_if_not(I first, S last, P pred, J value) 101 | { 102 | auto&& p = make_invokable(pred); 103 | while (first != last) { 104 | if (not p(*first)) ++value; 105 | ++first; 106 | } 107 | return value; 108 | } 109 | 110 | 111 | template 112 | requires Sentinel() and Invokable_predicate>() 113 | inline Difference_type 114 | count_if_not(I first, S last, P pred) 115 | { 116 | using J = Difference_type; 117 | return origin::count_if_not(first, last, pred, J{0}); 118 | } 119 | 120 | 121 | template 122 | requires Invokable_predicate>() 123 | inline Size_type 124 | count_if_not(R&& range, P pred, J value) 125 | { 126 | return origin::count_if_not(std::begin(range), std::end(range), pred, value); 127 | } 128 | 129 | template 130 | requires Invokable_predicate>() 131 | inline Size_type 132 | count_if_not(R&& range, P pred) 133 | { 134 | using J = Size_type; 135 | return origin::count_if_not(std::begin(range), std::end(range), pred, J{0}); 136 | } 137 | 138 | 139 | template 140 | requires Invokable_predicate() 141 | inline std::size_t 142 | count_if_not(std::initializer_list list, P pred, J value) 143 | { 144 | return origin::count_if_not(list.begin(), list.end(), pred, value); 145 | } 146 | 147 | 148 | template 149 | requires Invokable_predicate() 150 | inline std::size_t 151 | count_if_not(std::initializer_list list, P pred) 152 | { 153 | return origin::count_if_not(list.begin(), list.end(), pred, std::size_t{0}); 154 | } 155 | 156 | 157 | // -------------------------------------------------------------------------- // 158 | // Count [algo.count] // 159 | // 160 | // count(first, last, value, n) 161 | // count(first, last, value) 162 | // count(range, value, n) 163 | // count(range, value) 164 | // 165 | // TODO: Consider adding overloads that accept a binary relation. 166 | 167 | template 168 | requires Sentinel() and Equality_comparable>() 169 | inline N 170 | count(I first, S last, const T& value, N n) 171 | { 172 | while (first != last) { 173 | if (*first == value) ++n; 174 | } 175 | return n; 176 | } 177 | 178 | 179 | template 180 | requires Sentinel() and Equality_comparable>() 181 | inline Difference_type 182 | count(I first, S last, const T& value) 183 | { 184 | Difference_type n = 0; 185 | return origin::count(first, last, value, n); 186 | } 187 | 188 | 189 | template 190 | requires Equality_comparable, T>() 191 | inline Size_type 192 | count(R&& range, const T& value, N n) 193 | { 194 | return origin::count(std::begin(range), std::end(range), value, n); 195 | } 196 | 197 | 198 | template 199 | requires Equality_comparable, T>() 200 | inline Size_type 201 | count(R&& range, const T& value) 202 | { 203 | Size_type n = 0; 204 | return origin::count(std::begin(range), std::end(range), value, n); 205 | } 206 | 207 | 208 | template 209 | requires Equality_comparable() 210 | inline std::size_t 211 | count(std::initializer_list list, const T& value, N n) 212 | { 213 | return origin::count(list.begin(), list.end(), value, n); 214 | } 215 | 216 | 217 | template 218 | requires Equality_comparable() 219 | inline std::size_t 220 | count(std::initializer_list list, const T& value) 221 | { 222 | std::size_t n = 0; 223 | return origin::count(list.begin(), list.end(), value); 224 | } 225 | 226 | 227 | } // namesapce origin 228 | 229 | 230 | #endif 231 | -------------------------------------------------------------------------------- /origin/algorithm/equal.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include "equal.hpp" 5 | -------------------------------------------------------------------------------- /origin/algorithm/equal.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #ifndef ORIGIN_ALGORITHM_EQUAL_HPP 5 | #define ORIGIN_ALGORITHM_EQUAL_HPP 6 | 7 | #include 8 | 9 | #include 10 | 11 | 12 | namespace origin 13 | { 14 | 15 | 16 | // -------------------------------------------------------------------------- // 17 | // Equal [algo.equal] // 18 | 19 | template 20 | requires Equality_comparable, Value_type>() 21 | inline bool 22 | equal(I1 first1, I1 last1, I2 first2) 23 | { 24 | while (first1 != last1) { 25 | if (*first1 != *first2) 26 | return false; 27 | ++first1; 28 | ++first2; 29 | } 30 | return true; 31 | } 32 | 33 | 34 | template 35 | requires Relation, Value_type>() 36 | inline bool 37 | equal(I1 first1, I1 last1, I2 first2, C cmp) 38 | { 39 | while (first1 != last1) { 40 | if (!cmp(*first1, *first2)) 41 | return false; 42 | ++first1; 43 | ++first2; 44 | } 45 | return true; 46 | } 47 | 48 | 49 | template 50 | requires Indirectly_range_equal() 51 | inline bool 52 | equal(R1&& range1, R2&& range2) 53 | { 54 | using std::begin; 55 | using std::end; 56 | return origin::equal(begin(range1), end(range1), begin(range2)); 57 | } 58 | 59 | 60 | template 61 | requires Indirectly_range_comparable() 62 | inline bool 63 | equal(R1&& range1, R2&& range2, C comp) 64 | { 65 | using std::begin; 66 | using std::end; 67 | return origin::equal(begin(range1), end(range1), begin(range2), comp); 68 | } 69 | 70 | 71 | } // namesapce origin 72 | 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /origin/algorithm/find.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include "find.hpp" 5 | -------------------------------------------------------------------------------- /origin/algorithm/find.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #ifndef ORIGIN_ALGORITHM_FIND_HPP 5 | #define ORIGIN_ALGORITHM_FIND_HPP 6 | 7 | #include 8 | 9 | #include 10 | 11 | 12 | namespace origin 13 | { 14 | 15 | // -------------------------------------------------------------------------- // 16 | // Find If [algo.find_if] // 17 | // 18 | // find_if(first, last, pred) 19 | // find_if(range, pred) 20 | 21 | template 22 | requires Sentinel() && Invokable_predicate>() 23 | inline I 24 | find_if(I first, S last, P pred) 25 | { 26 | auto&& p = make_invokable(pred); 27 | while (first != last && !p(*first)) 28 | ++first; 29 | return first; 30 | } 31 | 32 | 33 | template 34 | requires Invokable_predicate>() 35 | inline Iterator_type 36 | find_if(R&& range, P pred) 37 | { 38 | return origin::find_if(std::begin(range), std::end(range), pred); 39 | } 40 | 41 | 42 | template 43 | requires Invokable_predicate() 44 | inline const T* 45 | find_if(std::initializer_list list, P pred) 46 | { 47 | return origin::find_if(list.begin(), list.end(), pred); 48 | } 49 | 50 | 51 | // -------------------------------------------------------------------------- // 52 | // Find If Not [algo.find_if_not] // 53 | // 54 | // find_if_not(first, last, pred) 55 | // find_if_not(range, pred) 56 | 57 | template 58 | requires Sentinel() and Invokable_predicate>() 59 | inline I 60 | find_if_not(I first, S last, P pred) { 61 | auto&& p = make_invokable(pred); 62 | while (first != last and p(*first)) 63 | ++first; 64 | return first; 65 | } 66 | 67 | 68 | template 69 | requires Invokable_predicate>() 70 | inline Iterator_type 71 | find_if_not(R&& range, P pred) 72 | { 73 | return std::find_if_not(begin(range), end(range), pred); 74 | } 75 | 76 | 77 | template 78 | requires Invokable_predicate() 79 | inline const T* 80 | find_if_not(std::initializer_list list, P pred) 81 | { 82 | return origin::find_if(list.begin(), list.end(), pred); 83 | } 84 | 85 | 86 | // -------------------------------------------------------------------------- // 87 | // Find [algo.find] // 88 | // 89 | // find(first, last, value) 90 | // find(range, value) 91 | // 92 | // TODO: Consider adding overloads that accept a binary relation. 93 | 94 | template 95 | requires Sentinel() and Equality_comparable>() 96 | inline I 97 | find(I first, S last, const T& value) 98 | { 99 | while (first != last and *first != value) 100 | ++first; 101 | return first; 102 | } 103 | 104 | template 105 | requires Equality_comparable>() 106 | inline Iterator_type 107 | find(R&& range, const T& value) 108 | { 109 | return origin::find(std::begin(range), std::end(range), value); 110 | } 111 | 112 | 113 | // -------------------------------------------------------------------------- // 114 | // Adjacent Find [algo.adj_find] // 115 | // 116 | 117 | template 118 | requires Sentinel() and Equality_comparable>() 119 | inline I 120 | find_adjacent(I first, S last, C comp) 121 | { 122 | if (first == last) return first; 123 | I prev = first; 124 | ++first; 125 | while (first != last and comp(*prev, *first)) { 126 | ++prev; 127 | ++first; 128 | } 129 | return prev; 130 | } 131 | 132 | 133 | template 134 | requires Sentinel() and Equality_comparable>() 135 | inline I 136 | find_adjacent(I first, S last) 137 | { 138 | return origin::find_adjacent(first, last, eq()); 139 | } 140 | 141 | 142 | template 143 | requires Equality_comparable>() 144 | inline Iterator_type 145 | find_adjacent(R&& range) 146 | { 147 | return origin::find_adjacent(std::begin(range), std::end(range), eq()); 148 | } 149 | 150 | 151 | template 152 | requires Relation>() 153 | inline Iterator_type 154 | find_adjacent(R&& range, C comp) 155 | { 156 | return origin::find_adjacent(std::begin(range), std::end(range), comp); 157 | } 158 | 159 | 160 | template 161 | inline const T* 162 | find_adjacent(std::initializer_list list) 163 | { 164 | return origin::find_adjacent(list.begin(), list.end(), eq()); 165 | } 166 | 167 | 168 | template 169 | requires Relation() 170 | inline const T* 171 | find_adjacent(std::initializer_list list, C comp) 172 | { 173 | return origin::find_adjacent(list.begin(), list.end(), comp); 174 | } 175 | 176 | 177 | // -------------------------------------------------------------------------- // 178 | // Mismatch [algo.mismatch] // 179 | 180 | template 181 | requires Relation, Value_type>() 182 | inline std::pair 183 | find_mismatch(I1 first1, I1 last1, I2 first2, C comp) 184 | { 185 | while (first1 != last1 and comp(*first1, *first2)) { 186 | ++first1; 187 | ++first2; 188 | } 189 | return {first1, first2}; 190 | } 191 | 192 | 193 | template 194 | requires Equality_comparable, Value_type>() 195 | inline std::pair 196 | find_mismatch(I1 first1, I1 last1, I2 first2) 197 | { 198 | return origin::find_mismatch(first1, last1, first2, eq()); 199 | } 200 | 201 | 202 | template 203 | requires Relation, Value_type>() 204 | inline std::pair, Iterator_type> 205 | find_mismatch(R1&& range1, R2&& range2, C comp) 206 | { 207 | using std::begin; 208 | using std::end; 209 | return origin::find_mismatch(begin(range1), end(range1), 210 | begin(range2), comp); 211 | } 212 | 213 | 214 | template 215 | requires Equality_comparable, Value_type>() 216 | inline std::pair, Iterator_type> 217 | find_mismatch(R1&& range1, R2&& range2) 218 | { 219 | using std::begin; 220 | using std::end; 221 | return origin::find_mismatch(begin(range1), end(range1), 222 | begin(range2), eq()); 223 | } 224 | 225 | 226 | // find_first_of 227 | template 228 | requires Indirectly_range_equal() 229 | inline Iterator_type 230 | find_first_of(R1&& range1, R2&& range2) 231 | { 232 | using std::begin; 233 | using std::end; 234 | return std::find_first_of(begin(range1), end(range1), 235 | begin(range2), end(range2)); 236 | } 237 | 238 | 239 | template 240 | requires Indirectly_range_comparable() 241 | inline Iterator_type 242 | find_first_of(R1&& range1, R2&& range2, C comp) 243 | { 244 | using std::begin; 245 | using std::end; 246 | return std::find_first_of(begin(range1), end(range1), 247 | begin(range2), end(range2), comp); 248 | } 249 | 250 | 251 | // find_end 252 | template 253 | requires Indirectly_range_equal() 254 | inline Iterator_type 255 | find_end(R1&& range1, R2&& range2) 256 | { 257 | using std::begin; 258 | using std::end; 259 | return std::find_end(begin(range1), end(range1), 260 | begin(range2), end(range2)); 261 | } 262 | 263 | 264 | template 265 | requires Indirectly_range_comparable() 266 | inline Iterator_type 267 | find_end(R1&& range1, R2&& range2, C comp) 268 | { 269 | using std::begin; 270 | using std::end; 271 | return std::find_end(begin(range1), end(range1), 272 | begin(range2), end(range2), comp); 273 | } 274 | 275 | 276 | } // namesapce origin 277 | 278 | 279 | #endif 280 | -------------------------------------------------------------------------------- /origin/algorithm/foreach.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include "foreach.hpp" 5 | -------------------------------------------------------------------------------- /origin/algorithm/foreach.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #ifndef ORIGIN_ALGORITHM_FOREACH_HPP 5 | #define ORIGIN_ALGORITHM_FOREACH_HPP 6 | 7 | #include 8 | 9 | #include 10 | 11 | 12 | namespace origin 13 | { 14 | 15 | // -------------------------------------------------------------------------- // 16 | // For Each [algo.for_each] // 17 | // 18 | // for_each(first, last, fn) 19 | // for_each(range, fn) 20 | 21 | template 22 | requires Sentinel() && Invokable>() 23 | inline F 24 | for_each(I first, S last, F fn) 25 | { 26 | auto&& f = make_invokable(fn); 27 | while (first != last) { 28 | f(*first); 29 | ++first; 30 | } 31 | return fn; 32 | } 33 | 34 | 35 | template 36 | requires Invokable>() 37 | inline F 38 | for_each(R&& range, F fn) 39 | { 40 | return origin::for_each(std::begin(range), std::end(range), fn); 41 | } 42 | 43 | 44 | template 45 | requires Invokable() 46 | inline F 47 | for_each(std::initializer_list list, F fn) 48 | { 49 | return origin::for_each(list.begin(), list.end(), fn); 50 | } 51 | 52 | 53 | } // namesapce origin 54 | 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /origin/algorithm/quantifier.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include "quantifier.hpp" 5 | -------------------------------------------------------------------------------- /origin/algorithm/quantifier.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #ifndef ORIGIN_ALGORITHM_QUANTIFIER_HPP 5 | #define ORIGIN_ALGORITHM_QUANTIFIER_HPP 6 | 7 | #include 8 | 9 | namespace origin 10 | { 11 | 12 | 13 | // -------------------------------------------------------------------------- // 14 | // All Of [algo.all_of] // 15 | // 16 | // all_of(first, last, fn) 17 | // all_of(range, fn) 18 | 19 | template 20 | requires Sentinel() and Invokable_predicate>() 21 | inline bool 22 | all_of(I first, S last, P pred) 23 | { 24 | return origin::find_if_not(first, last, pred) == last; 25 | } 26 | 27 | 28 | template 29 | requires Invokable_predicate>() 30 | inline bool 31 | all_of(R&& range, P pred) 32 | { 33 | using std::begin; 34 | using std::end; 35 | return origin::all_of(begin(range), end(range), pred); 36 | } 37 | 38 | 39 | // all_of (initializer_list) 40 | template 41 | requires Invokable_predicate() 42 | inline bool 43 | all_of(std::initializer_list list, P pred) 44 | { 45 | return origin::all_of(list.begin(), list.end(), pred); 46 | } 47 | 48 | 49 | // -------------------------------------------------------------------------- // 50 | // Any Of [algo.any_of] // 51 | // 52 | // any_of(first, last, fn) 53 | // any_of(range, fn) 54 | 55 | template 56 | requires Sentinel() and Invokable_predicate>() 57 | inline bool 58 | any_of(I first, S last, P pred) 59 | { 60 | return origin::find_if(first, last, pred) != last; 61 | } 62 | 63 | 64 | template 65 | requires Invokable_predicate>() 66 | inline bool 67 | any_of(R&& range, P pred) 68 | { 69 | using std::begin; 70 | using std::end; 71 | return origin::any_of(begin(range), end(range), pred); 72 | } 73 | 74 | template 75 | requires Invokable_predicate() 76 | inline bool 77 | any_of(std::initializer_list list, P pred) 78 | { 79 | return origin::any_of(list.begin(), list.end(), pred); 80 | } 81 | 82 | 83 | // -------------------------------------------------------------------------- // 84 | // None Of [algo.none_of] // 85 | // 86 | // none_of(first, last, fn) 87 | // none_of(range, fn) 88 | 89 | template 90 | requires Sentinel() and Invokable_predicate>() 91 | inline bool 92 | none_of(I first, S last, P pred) 93 | { 94 | return origin::find_if(first, last, pred) == last; 95 | } 96 | 97 | template 98 | requires Invokable_predicate>() 99 | inline bool 100 | none_of(R&& range, P pred) 101 | { 102 | using std::begin; 103 | using std::end; 104 | return origin::none_of(begin(range), end(range), pred); 105 | } 106 | 107 | template 108 | requires Invokable_predicate() 109 | inline bool 110 | none_of(std::initializer_list list, P pred) 111 | { 112 | return origin::none_of(list.begin(), list.end(), pred); 113 | } 114 | 115 | 116 | } // namesapce origin 117 | 118 | 119 | #endif 120 | -------------------------------------------------------------------------------- /origin/algorithm/uninitialized.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include "uninitialized.hpp" 5 | -------------------------------------------------------------------------------- /origin/algorithm/uninitialized.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #ifndef ORIGIN_ALGORITHM_UNINITIALIZED_HPP 5 | #define ORIGIN_ALGORITHM_UNINITIALIZED_HPP 6 | 7 | #include 8 | #include 9 | 10 | 11 | namespace origin 12 | { 13 | 14 | 15 | // Explicitly destroy the objects in the range [first, last). 16 | // 17 | // FIXME: This is wrong. 18 | template 19 | void 20 | destroy(I first, I last) 21 | { 22 | while (first != last) { 23 | destroy(&*first); 24 | ++first; 25 | } 26 | } 27 | 28 | 29 | // Copy initialize each element in the bounded range [first2, last2) 30 | // from the elements in the range [first1, last1) where last2 is 31 | // first2 + distance(first1, last1). 32 | // 33 | // Before this call, the memory in [first2, last) is uninitialized. 34 | // 35 | // FIXME: Write constraints. 36 | // 37 | // TODO: Optimize for noexcept copy constructors, and 38 | // for copies of trivial types. 39 | template 40 | I2 41 | uninitialized_copy(I1 first1, I1 last1, I2 first2) 42 | { 43 | I2 iter = first2; 44 | while (first1 != last1) { 45 | try { 46 | construct(&*iter, *first1); 47 | } catch (...) { 48 | destroy(first2, iter); 49 | throw; 50 | } 51 | ++first1; 52 | ++iter; 53 | } 54 | return iter; 55 | } 56 | 57 | 58 | // Move initialize each element in the range [first2, last2) from the 59 | // elements in the range [first1, last1) where last2 is 60 | // first2 + distance(first1, last1). 61 | // 62 | // Before this call, the memory in [first2, last) is uninitialized. 63 | // 64 | // FIXME: Write constraints. 65 | // 66 | // TODO: Optimize for noexcept move constructors, and 67 | // for copies of trivial types. 68 | template 69 | I2 70 | uninitialized_move(I1 first1, I1 last1, I2 first2) 71 | { 72 | I2 iter = first2; 73 | while (first1 != last1) { 74 | try { 75 | construct(&*iter, std::move(*first1)); 76 | } catch (...) { 77 | destroy(first2, iter); 78 | throw; 79 | } 80 | ++first1; 81 | ++iter; 82 | } 83 | return iter; 84 | } 85 | 86 | 87 | } // namespace origin 88 | 89 | 90 | #endif 91 | -------------------------------------------------------------------------------- /origin/core/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2009-2015 Andrew Sutton 2 | # All rights reserved 3 | 4 | include(CheckCXXSymbolExists) 5 | include(GenerateExportHeader) 6 | 7 | # Set variables. 8 | 9 | # Add options. 10 | 11 | # Run platform checks. 12 | check_cxx_symbol_exists("std::to_string(std::size_t)" "string" HAVE_STD_TO_STRING) 13 | set(ORIGIN_HAVE_STD_TO_STRING ${HAVE_STD_TO_STRING}) 14 | 15 | # Set compiler and linker flags. 16 | add_compiler_export_flags() 17 | 18 | # Add a library. 19 | add_library(origin-core STATIC 20 | traits.cpp 21 | concepts.cpp 22 | function.cpp 23 | finally.cpp 24 | type.cpp) 25 | 26 | target_compile_options(origin-core PUBLIC -std=c++1z -fconcepts) 27 | target_include_directories(origin-core 28 | PUBLIC "$") 29 | 30 | add_dependencies(check origin-core) 31 | 32 | # Generate the configuration header. 33 | configure_file(config.hpp.in config.hpp) 34 | 35 | # Generate the export header. 36 | generate_export_header(origin-core EXPORT_FILE_NAME export.hpp) 37 | 38 | # Add subdirectories. 39 | add_subdirectory(concepts.test) 40 | add_subdirectory(function.test) 41 | add_subdirectory(finally.test) 42 | 43 | # Add install targets. 44 | install( 45 | TARGETS origin-core 46 | EXPORT OriginTargets 47 | RUNTIME DESTINATION ${INSTALL_BIN_DIR} 48 | LIBRARY DESTINATION ${INSTALL_LIB_DIR} 49 | ARCHIVE DESTINATION ${INSTALL_LIB_DIR} 50 | INCLUDES DESTINATION ${INSTALL_INCLUDE_DIR} 51 | ) 52 | -------------------------------------------------------------------------------- /origin/core/concepts.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include "concepts.hpp" 5 | -------------------------------------------------------------------------------- /origin/core/concepts.test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2009-2015 Andrew Sutton 2 | # All rights reserved 3 | 4 | link_libraries(origin-core) 5 | 6 | add_run_test(core_same same.cpp) 7 | add_run_test(core_derived derived.cpp) 8 | add_run_test(core_convertible convertible.cpp) 9 | add_run_test(core_common_type common_type.cpp) 10 | add_run_test(core_common common.cpp) 11 | 12 | add_run_test(core_void void.cpp) 13 | add_run_test(core_character character.cpp) 14 | add_run_test(core_signed_integer signed_integer.cpp) 15 | add_run_test(core_unsigned_integer unsigned_integer.cpp) 16 | add_run_test(core_integral integral.cpp) 17 | 18 | add_run_test(core_boolean boolean.cpp) 19 | add_run_test(core_equality_comparable equality_comparable.cpp) 20 | add_run_test(core_weakly_ordered weakly_ordered.cpp) 21 | add_run_test(core_totally_ordered totally_ordered.cpp) 22 | add_run_test(core_destructible destructible.cpp) 23 | add_run_test(core_constructible constructible.cpp) 24 | add_run_test(core_assignable assignable.cpp) 25 | add_run_test(core_default_constructible default_constructible.cpp) 26 | add_run_test(core_move_constructible move_constructible.cpp) 27 | add_run_test(core_move_assignable move_assignable.cpp) 28 | add_run_test(core_copy_constructible copy_constructible.cpp) 29 | add_run_test(core_copy_assignable copy_assignable.cpp) 30 | add_run_test(core_movable movable.cpp) 31 | add_run_test(core_copyable copyable.cpp) 32 | add_run_test(core_semiregular semiregular.cpp) 33 | add_run_test(core_regular regular.cpp) 34 | add_run_test(core_ordered ordered.cpp) 35 | 36 | add_run_test(core_function function.cpp) 37 | add_run_test(core_predicate predicate.cpp) 38 | add_run_test(core_relation relation.cpp) 39 | add_run_test(core_unary_operation unary_operation.cpp) 40 | add_run_test(core_binary_operation binary_operation.cpp) 41 | 42 | add_run_test(core_value_type value_type.cpp) 43 | add_run_test(core_difference_type difference_type.cpp) 44 | -------------------------------------------------------------------------------- /origin/core/concepts.test/assignable.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | 7 | template void test(); 8 | 9 | template 10 | requires origin::Assignable() 11 | void test() { } 12 | 13 | int main() 14 | { 15 | test(); 16 | test(); 17 | test(); 18 | test(); 19 | } 20 | -------------------------------------------------------------------------------- /origin/core/concepts.test/binary_operation.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | int main() { return 0; } 7 | -------------------------------------------------------------------------------- /origin/core/concepts.test/boolean.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | 7 | struct B0 8 | { 9 | explicit operator bool() const { return true; } 10 | }; 11 | 12 | 13 | struct B1 14 | { 15 | operator bool() const { return true; } 16 | }; 17 | 18 | 19 | struct B2 20 | { 21 | explicit operator bool() const { return true; } 22 | int operator!() const { return 0; } 23 | }; 24 | 25 | 26 | static_assert(origin::Boolean(), ""); 27 | static_assert(origin::Boolean(), ""); 28 | static_assert(origin::Boolean(), ""); 29 | static_assert(origin::Boolean(), ""); 30 | static_assert(!origin::Boolean(), ""); 31 | 32 | int main() { return 0; } 33 | -------------------------------------------------------------------------------- /origin/core/concepts.test/character.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | using namespace origin; 7 | 8 | template 9 | void 10 | check_narrow_character() 11 | { 12 | static_assert(Narrow_character_type(), ""); 13 | static_assert(Narrow_character_type(), ""); 14 | static_assert(Narrow_character_type(), ""); 15 | static_assert(Narrow_character_type(), ""); 16 | } 17 | 18 | template 19 | void 20 | check_wide_character() 21 | { 22 | static_assert(Wide_character_type(), ""); 23 | static_assert(Wide_character_type(), ""); 24 | static_assert(Wide_character_type(), ""); 25 | static_assert(Wide_character_type(), ""); 26 | } 27 | 28 | int 29 | main() 30 | { 31 | check_narrow_character(); 32 | check_narrow_character(); 33 | check_narrow_character(); 34 | 35 | check_wide_character(); 36 | check_wide_character(); 37 | check_wide_character(); 38 | } 39 | -------------------------------------------------------------------------------- /origin/core/concepts.test/common.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | static_assert(origin::Common(), ""); 7 | static_assert(origin::Common(), ""); 8 | static_assert(origin::Common(), ""); 9 | static_assert(origin::Common(), ""); 10 | 11 | static_assert(origin::Common(), ""); 12 | static_assert(origin::Common(), ""); 13 | static_assert(origin::Common(), ""); 14 | static_assert(origin::Common(), ""); 15 | 16 | static_assert(origin::Common(), ""); 17 | 18 | // TODO: Write more tests. 19 | 20 | int main() { return 0; } 21 | -------------------------------------------------------------------------------- /origin/core/concepts.test/common_type.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | // True when Common_type is the same as C. 7 | template 8 | constexpr bool Has_common_type() 9 | { 10 | return origin::Same, C>(); 11 | } 12 | 13 | static_assert(Has_common_type(), ""); 14 | static_assert(Has_common_type(), ""); 15 | static_assert(Has_common_type(), ""); 16 | static_assert(Has_common_type(), ""); 17 | 18 | static_assert(Has_common_type(), ""); 19 | static_assert(Has_common_type(), ""); 20 | static_assert(Has_common_type(), ""); 21 | static_assert(Has_common_type(), ""); 22 | 23 | static_assert(Has_common_type(), ""); 24 | 25 | // TODO: Write more tests. 26 | 27 | int main() { } 28 | -------------------------------------------------------------------------------- /origin/core/concepts.test/constructible.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | static_assert(origin::Constructible(), ""); 7 | static_assert(origin::Constructible(), ""); 8 | 9 | static_assert(origin::Constructible(), ""); 10 | static_assert(origin::Constructible(), ""); 11 | static_assert(origin::Constructible(), ""); 12 | static_assert(origin::Constructible(), ""); 13 | 14 | // TODO: Write more tests 15 | 16 | int main() { return 0; } 17 | -------------------------------------------------------------------------------- /origin/core/concepts.test/convertible.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | static_assert(origin::Convertible(), ""); 7 | static_assert(origin::Convertible(), ""); 8 | static_assert(origin::Convertible(), ""); 9 | static_assert(origin::Convertible(), ""); 10 | static_assert(origin::Convertible(), ""); 11 | static_assert(origin::Convertible(), ""); 12 | static_assert(origin::Convertible(), ""); 13 | 14 | static_assert(not origin::Convertible(), ""); 15 | static_assert(not origin::Convertible(), ""); 16 | static_assert(not origin::Convertible(), ""); 17 | static_assert(not origin::Convertible(), ""); 18 | 19 | static_assert(origin::Convertible(), ""); 20 | static_assert(origin::Convertible(), ""); 21 | static_assert(not origin::Convertible(), ""); 22 | static_assert(not origin::Convertible(), ""); 23 | 24 | static_assert(origin::Convertible(), ""); 25 | 26 | static_assert(origin::Convertible(), ""); 27 | static_assert(origin::Convertible(), ""); 28 | 29 | static_assert(origin::Convertible(), ""); 30 | static_assert(origin::Convertible(), ""); 31 | 32 | // TODO: Write more tests. Obviously... 33 | 34 | int main() { return 0; } 35 | -------------------------------------------------------------------------------- /origin/core/concepts.test/copy_assignable.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | struct S0 7 | { 8 | }; 9 | 10 | struct S1 11 | { 12 | S1& operator=(S1 const&) = default; 13 | }; 14 | 15 | struct S2 16 | { 17 | S2& operator=(S2 const&) = delete; 18 | }; 19 | 20 | class S3 21 | { 22 | S3& operator=(S3 const&) = delete; 23 | }; 24 | 25 | 26 | static_assert(origin::Copy_assignable(), ""); 27 | static_assert(origin::Copy_assignable(), ""); 28 | static_assert(origin::Copy_assignable(), ""); 29 | static_assert(!origin::Copy_assignable(), ""); 30 | static_assert(!origin::Copy_assignable(), ""); 31 | 32 | int main() { return 0; } 33 | -------------------------------------------------------------------------------- /origin/core/concepts.test/copy_constructible.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | struct S0 7 | { 8 | }; 9 | 10 | struct S1 11 | { 12 | S1(const S1&) = default; 13 | }; 14 | 15 | struct S2 16 | { 17 | S2(const S2&) = delete; 18 | }; 19 | 20 | class S3 21 | { 22 | S3(const S3&) = delete; 23 | }; 24 | 25 | static_assert(origin::Copy_constructible(), ""); 26 | static_assert(origin::Copy_constructible(), ""); 27 | static_assert(origin::Copy_constructible(), ""); 28 | static_assert(!origin::Copy_constructible(), ""); 29 | static_assert(!origin::Copy_constructible(), ""); 30 | 31 | int main() { return 0; } 32 | -------------------------------------------------------------------------------- /origin/core/concepts.test/copyable.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | static_assert(origin::Copyable(), ""); 7 | 8 | int main() { return 0; } 9 | -------------------------------------------------------------------------------- /origin/core/concepts.test/default_constructible.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | struct S0 7 | { 8 | }; 9 | 10 | struct S1 11 | { 12 | S1() = default; 13 | }; 14 | 15 | struct S2 16 | { 17 | S2() = delete; 18 | }; 19 | 20 | class S3 21 | { 22 | S3(); 23 | }; 24 | 25 | static_assert(origin::Default_constructible(), ""); 26 | static_assert(origin::Default_constructible(), ""); 27 | static_assert(origin::Default_constructible(), ""); 28 | static_assert(!origin::Default_constructible(), ""); 29 | 30 | 31 | // FIXME: GCC reports this as valid. A class with a private 32 | // default constructor is apparently default constructible? 33 | static_assert(origin::Default_constructible(), ""); 34 | 35 | int main() 36 | { 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /origin/core/concepts.test/derived.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | struct B { }; 7 | struct D1 : B { }; 8 | class D2 : B { }; 9 | 10 | static_assert(origin::Derived(), ""); 11 | static_assert(origin::Derived(), ""); 12 | static_assert(!origin::Derived(), ""); 13 | 14 | // TODO: write tests for virtual inheritance. 15 | 16 | int 17 | main() { } 18 | -------------------------------------------------------------------------------- /origin/core/concepts.test/destructible.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | struct S0 7 | { 8 | }; 9 | 10 | struct S1 11 | { 12 | S1() = default; 13 | }; 14 | 15 | struct S2 16 | { 17 | ~S2() = delete; 18 | }; 19 | 20 | class S3 21 | { 22 | ~S3(); 23 | }; 24 | 25 | static_assert(origin::Destructible(), ""); 26 | static_assert(origin::Destructible(), ""); 27 | static_assert(origin::Destructible(), ""); 28 | static_assert(!origin::Destructible(), ""); 29 | 30 | // FIXME: GCC says that S3 is destructible despite having 31 | // a private destructor. 32 | static_assert(origin::Destructible(), ""); 33 | 34 | int main() { return 0; } 35 | -------------------------------------------------------------------------------- /origin/core/concepts.test/difference_type.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | // True when Difference_type is the same as U. 7 | template 8 | constexpr bool Has_difference_type() 9 | { 10 | return origin::Same, U>(); 11 | } 12 | 13 | struct S 14 | { 15 | using difference_type = int; 16 | }; 17 | 18 | static_assert(Has_difference_type(), ""); 19 | static_assert(Has_difference_type(), ""); 20 | static_assert(Has_difference_type(), ""); 21 | static_assert(Has_difference_type(), ""); 22 | static_assert(Has_difference_type(), ""); 23 | 24 | int main() { return 0; } 25 | -------------------------------------------------------------------------------- /origin/core/concepts.test/equality_comparable.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | struct S0 { }; 7 | 8 | struct S1 9 | { 10 | bool operator==(S1) const; 11 | }; 12 | 13 | struct S2 14 | { 15 | bool operator==(S2) const; 16 | bool operator!=(S2) const; 17 | }; 18 | 19 | static_assert(origin::Equality_comparable(), ""); 20 | static_assert(origin::Equality_comparable(), ""); 21 | static_assert(not origin::Equality_comparable(), ""); 22 | static_assert(not origin::Equality_comparable(), ""); 23 | static_assert(origin::Equality_comparable(), ""); 24 | 25 | static_assert(origin::Equality_comparable(), ""); 26 | static_assert(not origin::Equality_comparable(), ""); 27 | 28 | int main() { return 0; } 29 | -------------------------------------------------------------------------------- /origin/core/concepts.test/function.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | static_assert(origin::Function(), ""); 7 | 8 | int main() { return 0; } 9 | -------------------------------------------------------------------------------- /origin/core/concepts.test/integral.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | using namespace origin; 7 | 8 | template 9 | void 10 | check_integral() 11 | { 12 | static_assert(Integral_type(), ""); 13 | static_assert(Integral_type(), ""); 14 | static_assert(Integral_type(), ""); 15 | static_assert(Integral_type(), ""); 16 | } 17 | 18 | template 19 | constexpr int value(T) { return 0; } 20 | 21 | template 22 | constexpr int value(T) { return 1; } 23 | 24 | template 25 | constexpr int value(T) { return 2; } 26 | 27 | template 28 | constexpr int value(T) { return 3; } 29 | 30 | template 31 | constexpr int value(T) { return 4; } 32 | 33 | int 34 | main() 35 | { 36 | // Bool is integral 37 | check_integral(); 38 | 39 | // Character types are integral 40 | check_integral(); 41 | check_integral(); 42 | check_integral(); 43 | check_integral(); 44 | check_integral(); 45 | check_integral(); 46 | 47 | // Signed integers are integral 48 | check_integral(); 49 | check_integral(); 50 | check_integral(); 51 | check_integral(); 52 | check_integral(); 53 | 54 | // Unsigned integers are integral 55 | check_integral(); 56 | check_integral(); 57 | check_integral(); 58 | check_integral(); 59 | check_integral(); 60 | 61 | // Check ordering 62 | static_assert(value(true) == 0, ""); 63 | static_assert(value('a') == 1, ""); 64 | static_assert(value(L'a') == 2, ""); 65 | static_assert(value(0) == 3, ""); 66 | static_assert(value(0u) == 4, ""); 67 | } 68 | -------------------------------------------------------------------------------- /origin/core/concepts.test/movable.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | static_assert(origin::Movable(), ""); 7 | 8 | int main() { return 0; } 9 | -------------------------------------------------------------------------------- /origin/core/concepts.test/move_assignable.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | struct S0 7 | { 8 | }; 9 | 10 | struct S1 11 | { 12 | S1& operator=(S1&&) = default; 13 | }; 14 | 15 | struct S2 16 | { 17 | S2& operator=(S2&&) = delete; 18 | }; 19 | 20 | class S3 21 | { 22 | S3 operator=(S3&&) { } 23 | }; 24 | 25 | static_assert(origin::Move_assignable(), ""); 26 | static_assert(origin::Move_assignable(), ""); 27 | static_assert(origin::Move_assignable(), ""); 28 | static_assert(!origin::Move_assignable(), ""); 29 | 30 | // FIXME: Move assignable with a private destructor? 31 | static_assert(origin::Move_assignable(), ""); 32 | 33 | int main() { return 0; } 34 | -------------------------------------------------------------------------------- /origin/core/concepts.test/move_constructible.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | struct S0 7 | { 8 | }; 9 | 10 | struct S1 11 | { 12 | S1(S1&&) = default; 13 | }; 14 | 15 | struct S2 16 | { 17 | S2(S2&&) = delete; 18 | }; 19 | 20 | class S3 21 | { 22 | S3(S3&&) { } 23 | }; 24 | 25 | static_assert(origin::Move_constructible(), ""); 26 | static_assert(origin::Move_constructible(), ""); 27 | static_assert(origin::Move_constructible(), ""); 28 | static_assert(!origin::Move_constructible(), ""); 29 | 30 | // FIXME: Move constructible with a private constructor? 31 | static_assert(origin::Move_constructible(), ""); 32 | 33 | int main() { return 0; } 34 | -------------------------------------------------------------------------------- /origin/core/concepts.test/ordered.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | static_assert(origin::Ordered(), ""); 7 | 8 | int main() { return 0; } 9 | -------------------------------------------------------------------------------- /origin/core/concepts.test/predicate.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | int main() { return 0; } 7 | -------------------------------------------------------------------------------- /origin/core/concepts.test/regular.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | static_assert(origin::Regular(), ""); 7 | 8 | int main() { return 0; } 9 | -------------------------------------------------------------------------------- /origin/core/concepts.test/relation.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | int main() { return 0; } 7 | -------------------------------------------------------------------------------- /origin/core/concepts.test/same.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | static_assert(origin::Same(), ""); 7 | static_assert(!origin::Same(), ""); 8 | 9 | // TODO: Write more tests. 10 | 11 | int main() { return 0; } 12 | -------------------------------------------------------------------------------- /origin/core/concepts.test/semiregular.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | static_assert(origin::Semiregular(), ""); 7 | 8 | int main() { return 0; } 9 | -------------------------------------------------------------------------------- /origin/core/concepts.test/signed_integer.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | using namespace origin; 7 | 8 | template 9 | void 10 | check() 11 | { 12 | static_assert(Signed_integer_type(), ""); 13 | static_assert(Signed_integer_type(), ""); 14 | static_assert(Signed_integer_type(), ""); 15 | static_assert(Signed_integer_type(), ""); 16 | } 17 | 18 | int 19 | main() 20 | { 21 | check(); 22 | check(); 23 | check(); 24 | check(); 25 | check(); 26 | 27 | static_assert(!Signed_integer_type(), ""); 28 | static_assert(!Signed_integer_type(), ""); 29 | static_assert(!Signed_integer_type(), ""); 30 | } 31 | -------------------------------------------------------------------------------- /origin/core/concepts.test/totally_ordered.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | struct S0 { }; 7 | 8 | struct S1 9 | { 10 | bool operator==(S1) const; 11 | bool operator<(S1) const; 12 | }; 13 | 14 | struct S2 15 | { 16 | bool operator==(S2) const; 17 | bool operator!=(S2) const; 18 | bool operator<(S2) const; 19 | bool operator>(S2) const; 20 | bool operator<=(S2) const; 21 | bool operator>=(S2) const; 22 | }; 23 | 24 | static_assert(origin::Totally_ordered(), ""); 25 | static_assert(origin::Totally_ordered(), ""); 26 | static_assert(not origin::Totally_ordered(), ""); 27 | static_assert(not origin::Totally_ordered(), ""); 28 | static_assert(origin::Totally_ordered(), ""); 29 | 30 | static_assert(origin::Totally_ordered(), ""); 31 | static_assert(not origin::Totally_ordered(), ""); 32 | 33 | int main() { return 0; } 34 | -------------------------------------------------------------------------------- /origin/core/concepts.test/unary_operation.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | int main() { return 0; } 7 | -------------------------------------------------------------------------------- /origin/core/concepts.test/unsigned_integer.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | 7 | using namespace origin; 8 | 9 | template 10 | void 11 | check() 12 | { 13 | static_assert(Unsigned_integer_type(), ""); 14 | static_assert(Unsigned_integer_type(), ""); 15 | static_assert(Unsigned_integer_type(), ""); 16 | static_assert(Unsigned_integer_type(), ""); 17 | } 18 | 19 | int 20 | main() 21 | { 22 | check(); 23 | check(); 24 | check(); 25 | check(); 26 | check(); 27 | 28 | static_assert(!Unsigned_integer_type(), ""); 29 | static_assert(!Unsigned_integer_type(), ""); 30 | static_assert(!Unsigned_integer_type(), ""); 31 | } 32 | -------------------------------------------------------------------------------- /origin/core/concepts.test/value_type.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | 7 | // True when Value_type is the same as U. 8 | template 9 | constexpr bool 10 | Has_value_type() 11 | { 12 | return origin::Same, U>(); 13 | } 14 | 15 | struct S 16 | { 17 | using value_type = int; 18 | }; 19 | 20 | static_assert(Has_value_type(), ""); 21 | static_assert(Has_value_type(), ""); 22 | static_assert(Has_value_type(), ""); 23 | static_assert(Has_value_type(), ""); 24 | static_assert(Has_value_type(), ""); 25 | 26 | int main() { return 0; } 27 | -------------------------------------------------------------------------------- /origin/core/concepts.test/void.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | 7 | template 8 | void 9 | check_void() 10 | { 11 | static_assert(origin::Void_type(), ""); 12 | static_assert(origin::Void_type(), ""); 13 | static_assert(origin::Void_type(), ""); 14 | static_assert(origin::Void_type(), ""); 15 | } 16 | 17 | int 18 | main() 19 | { 20 | check_void(); 21 | } 22 | -------------------------------------------------------------------------------- /origin/core/concepts.test/weakly_ordered.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | struct S0 { }; 7 | 8 | struct S1 9 | { 10 | bool operator<(S1) const; 11 | }; 12 | 13 | struct S2 14 | { 15 | bool operator<(S2) const; 16 | bool operator>(S2) const; 17 | bool operator<=(S2) const; 18 | bool operator>=(S2) const; 19 | }; 20 | 21 | static_assert(origin::Weakly_ordered(), ""); 22 | static_assert(origin::Weakly_ordered(), ""); 23 | static_assert(!origin::Weakly_ordered(), ""); 24 | static_assert(!origin::Weakly_ordered(), ""); 25 | static_assert(origin::Weakly_ordered(), ""); 26 | 27 | static_assert(origin::Weakly_ordered(), ""); 28 | static_assert(!origin::Weakly_ordered(), ""); 29 | 30 | int main() { return 0; } 31 | -------------------------------------------------------------------------------- /origin/core/config.hpp.in: -------------------------------------------------------------------------------- 1 | /** 2 | * @file origin/core/config.hpp 3 | * The configuration header for the Origin.Core library. 4 | * 5 | * @date 2015 6 | * @version @ORIGIN_VERSION@ 7 | */ 8 | 9 | /* config.hpp. Generated from config.hpp.in by cmake. */ 10 | 11 | #ifndef ORIGIN_CORE_CONFIG_HPP 12 | #define ORIGIN_CORE_CONFIG_HPP 13 | 14 | /* Name of package. */ 15 | #define ORIGIN_PACKAGE "@ORIGIN_PACKAGE_NAME@" 16 | 17 | /* Define to the full name of this package. */ 18 | #define ORIGIN_PACKAGE_NAME "@ORIGIN_PACKAGE_NAME@" 19 | 20 | /* Define to the one symbol short name of this package. */ 21 | #define ORIGIN_PACKAGE_TARNAME "@ORIGIN_PACKAGE_TARNAME@" 22 | 23 | /* Define to the version of this package. */ 24 | #define ORIGIN_PACKAGE_VERSION "@ORIGIN_PACKAGE_VERSION@" 25 | 26 | /* Define to the full name and version of this package. */ 27 | #define ORIGIN_PACKAGE_STRING "@ORIGIN_PACKAGE_STRING@" 28 | 29 | /* Define to the address where bug reports for this package should be sent. */ 30 | #define ORIGIN_PACKAGE_BUGREPORT "@ORIGIN_PACKAGE_BUGREPORT@" 31 | 32 | /* Define to the home page for this package. */ 33 | #define ORIGIN_PACKAGE_URL "@ORIGIN_PACKAGE_URL@" 34 | 35 | /* The version number of the Origin libraries. */ 36 | #define ORIGIN_VERSION "@ORIGIN_VERSION@" 37 | 38 | /* The major version of the Origin libraries. */ 39 | #define ORIGIN_VERSION_MAJOR @ORIGIN_VERSION_MAJOR@ 40 | 41 | /* The minor version of the Origin libraries. */ 42 | #define ORIGIN_VERSION_MINOR @ORIGIN_VERSION_MINOR@ 43 | 44 | /* The patch version of the Origin libraries. */ 45 | #define ORIGIN_VERSION_PATCH @ORIGIN_VERSION_PATCH@ 46 | 47 | /* The tweak version of the Origin libraries. */ 48 | #define ORIGIN_VERSION_TWEAK @ORIGIN_VERSION_TWEAK@ 49 | 50 | /* Define to 1 if you have the std::to_string() function. */ 51 | #cmakedefine ORIGIN_HAVE_STD_TO_STRING 1 52 | 53 | #include 54 | 55 | #endif // ORIGIN_CORE_CONFIG_HPP 56 | -------------------------------------------------------------------------------- /origin/core/finally.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include "finally.hpp" 5 | -------------------------------------------------------------------------------- /origin/core/finally.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #ifndef ORIGIN_CORE_FINALLY_HPP 5 | #define ORIGIN_CORE_FINALLY_HPP 6 | 7 | #include 8 | 9 | 10 | // The finally keyword allows the registration of a function 11 | // to be executed at the end of the enclosing scope. This 12 | // help simplify the definition of algorithms with multiple 13 | // exit paths that are nonetheless required to release resources 14 | // prior to exit. 15 | // 16 | // Example: 17 | // 18 | // void read(char const* path) 19 | // { 20 | // FILE* f = fopen(path, "rt"); 21 | // finally([&f] { if (f) fclose(f); }); 22 | // // do stuff. 23 | // } 24 | // 25 | // Regardless of how `read` exists, the file pointer is closed 26 | // before returining. 27 | #define finally(f) \ 28 | auto guard__ ## __COUNTER__ = origin::make_finally(f) 29 | 30 | 31 | namespace origin 32 | { 33 | 34 | // The final act class invokes its function when it destroyed. 35 | // `F` must be a nullary function. The return value is discarded. 36 | // 37 | // This class is almost never used directly. Instead, use the 38 | // finally macro. 39 | template 40 | struct final_act 41 | { 42 | final_act(F f) 43 | : fn(f) 44 | { } 45 | 46 | ~final_act() { fn(); } 47 | 48 | F fn; 49 | }; 50 | 51 | 52 | template 53 | inline final_act 54 | make_finally(F fn) 55 | { 56 | return final_act(fn); 57 | } 58 | 59 | 60 | } // namespace origin 61 | 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /origin/core/finally.test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2009-2015 Andrew Sutton 2 | # All rights reserved 3 | 4 | link_libraries(origin-core) 5 | 6 | add_run_test(core_finally finally.cpp) 7 | -------------------------------------------------------------------------------- /origin/core/finally.test/finally.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | #include 7 | 8 | void 9 | test_1(int n) 10 | { 11 | finally([=] { 12 | std::cout << "exit"; 13 | }); 14 | 15 | if (n < 0) 16 | return; 17 | if (n > 0); 18 | return; 19 | return; 20 | } 21 | 22 | 23 | int 24 | main() 25 | { 26 | test_1(-1); 27 | test_1( 0); 28 | test_1( 1); 29 | } 30 | -------------------------------------------------------------------------------- /origin/core/function.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include "function.hpp" 5 | -------------------------------------------------------------------------------- /origin/core/function.test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2009-2015 Andrew Sutton 2 | # All rights reserved 3 | 4 | link_libraries(origin-core) 5 | 6 | add_run_test(core_invoke invoke.cpp) 7 | -------------------------------------------------------------------------------- /origin/core/function.test/invoke.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | #include 7 | 8 | 9 | struct X { }; 10 | 11 | bool even(int n) { return n % 2 == 0; } 12 | 13 | struct even_fn 14 | { 15 | bool operator()(int n) const { return even(n); } 16 | }; 17 | 18 | struct S { 19 | void f() { } 20 | void fc() const { } 21 | void g(int) { } 22 | }; 23 | 24 | static_assert(origin::Invokable(), ""); 25 | 26 | static_assert(origin::Invokable(), ""); 27 | 28 | static_assert(origin::Invokable(), ""); 29 | static_assert(origin::Invokable(), ""); 30 | static_assert(origin::Invokable(), ""); 31 | 32 | static_assert(!origin::Invokable(), ""); 33 | 34 | 35 | int main() { } 36 | -------------------------------------------------------------------------------- /origin/core/semantics.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include "semantics.hpp" 5 | -------------------------------------------------------------------------------- /origin/core/semantics.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #ifndef ORIGIN_CORE_SEMANTICS_HPP 5 | #define ORIGIN_CORE_SEMANTICS_HPP 6 | 7 | #include 8 | 9 | // Terminate the program if the precondition `e` evaluates 10 | // to false. 11 | #define expects(e) assert(e) 12 | 13 | // Terminates the program if the postcondition `e` evalautes 14 | // to false. 15 | #define ensures(e) assert(e) 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /origin/core/traits.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include "traits.hpp" 5 | -------------------------------------------------------------------------------- /origin/core/type.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include "type.hpp" 5 | 6 | #include 7 | 8 | #if defined(__GNUC__) 9 | # include 10 | #endif 11 | 12 | 13 | namespace origin 14 | { 15 | 16 | // Return the string represntation of a type info object. 17 | #if defined(__GNUC__) 18 | 19 | std::string 20 | typestr(std::type_info const& info) 21 | { 22 | std::size_t n = 0; 23 | char* buf = abi::__cxa_demangle(info.name(), nullptr, &n, 0); 24 | std::string result(buf, n); 25 | std::free(buf); 26 | return result; 27 | } 28 | 29 | #else 30 | # error No compiler support for rendering type names 31 | #endif 32 | 33 | } // namespace origin 34 | -------------------------------------------------------------------------------- /origin/data/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2009-2015 Andrew Sutton 2 | # All rights reserved 3 | 4 | include(GenerateExportHeader) 5 | 6 | # Set variables. 7 | 8 | # Add options. 9 | # option(ORIGIN_USE_SSO "Enable the short/small string optimization." ON) 10 | 11 | # Run platform checks. 12 | 13 | # Set compiler and linker flags. 14 | add_compiler_export_flags() 15 | 16 | # Add the library. 17 | add_library(origin-data STATIC 18 | vector.cpp) 19 | 20 | target_compile_options(origin-data PUBLIC -std=c++1z -fconcepts) 21 | target_include_directories(origin-data 22 | PUBLIC "$") 23 | target_link_libraries(origin-data 24 | PUBLIC origin-iterator origin-memory origin-range) 25 | 26 | add_dependencies(check origin-data) 27 | 28 | # Generate the configuration header. 29 | configure_file(config.hpp.in config.hpp) 30 | 31 | # Generate the export header. 32 | generate_export_header(origin-data EXPORT_FILE_NAME export.hpp) 33 | 34 | # Add subdirectories. 35 | # TODO: Add tests. 36 | 37 | # Add install targets. 38 | install( 39 | TARGETS origin-data 40 | EXPORT OriginTargets 41 | RUNTIME DESTINATION ${INSTALL_BIN_DIR} 42 | LIBRARY DESTINATION ${INSTALL_LIB_DIR} 43 | ARCHIVE DESTINATION ${INSTALL_LIB_DIR} 44 | INCLUDES DESTINATION ${INSTALL_INCLUDE_DIR} 45 | ) 46 | -------------------------------------------------------------------------------- /origin/data/config.hpp.in: -------------------------------------------------------------------------------- 1 | /** 2 | * @file origin/data/config.hpp 3 | * The configuration header for the Origin.Data library. 4 | * 5 | * @date 2015 6 | * @version @ORIGIN_VERSION@ 7 | */ 8 | 9 | /* config.hpp. Generated from config.hpp.in by cmake. */ 10 | 11 | #ifndef ORIGIN_DATA_CONFIG_HPP 12 | #define ORIGIN_DATA_CONFIG_HPP 13 | 14 | /* Name of package. */ 15 | #define ORIGIN_PACKAGE "@ORIGIN_PACKAGE_NAME@" 16 | 17 | /* Define to the full name of this package. */ 18 | #define ORIGIN_PACKAGE_NAME "@ORIGIN_PACKAGE_NAME@" 19 | 20 | /* Define to the one symbol short name of this package. */ 21 | #define ORIGIN_PACKAGE_TARNAME "@ORIGIN_PACKAGE_TARNAME@" 22 | 23 | /* Define to the version of this package. */ 24 | #define ORIGIN_PACKAGE_VERSION "@ORIGIN_PACKAGE_VERSION@" 25 | 26 | /* Define to the full name and version of this package. */ 27 | #define ORIGIN_PACKAGE_STRING "@ORIGIN_PACKAGE_STRING@" 28 | 29 | /* Define to the address where bug reports for this package should be sent. */ 30 | #define ORIGIN_PACKAGE_BUGREPORT "@ORIGIN_PACKAGE_BUGREPORT@" 31 | 32 | /* Define to the home page for this package. */ 33 | #define ORIGIN_PACKAGE_URL "@ORIGIN_PACKAGE_URL@" 34 | 35 | /* The version number of the Origin libraries. */ 36 | #define ORIGIN_VERSION "@ORIGIN_VERSION@" 37 | 38 | /* The major version of the Origin libraries. */ 39 | #define ORIGIN_VERSION_MAJOR @ORIGIN_VERSION_MAJOR@ 40 | 41 | /* The minor version of the Origin libraries. */ 42 | #define ORIGIN_VERSION_MINOR @ORIGIN_VERSION_MINOR@ 43 | 44 | /* The patch version of the Origin libraries. */ 45 | #define ORIGIN_VERSION_PATCH @ORIGIN_VERSION_PATCH@ 46 | 47 | /* The tweak version of the Origin libraries. */ 48 | #define ORIGIN_VERSION_TWEAK @ORIGIN_VERSION_TWEAK@ 49 | 50 | #include 51 | 52 | #endif // ORIGIN_DATA_CONFIG_HPP 53 | -------------------------------------------------------------------------------- /origin/data/vector.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include "vector.hpp" 5 | -------------------------------------------------------------------------------- /origin/functional.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #ifndef ORIGIN_FUNCTIONAL_HPP 5 | #define ORIGIN_FUNCTIONAL_HPP 6 | 7 | #include 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /origin/generic.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #ifndef ORIGIN_GENERIC_HPP 5 | #define ORIGIN_GENERIC_HPP 6 | 7 | // Core traits and concepts. 8 | #include 9 | 10 | // Finally "keyword". 11 | #include 12 | 13 | // Pretty printing types. 14 | #include 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /origin/iterator.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #ifndef ORIGIN_ITERATOR_HPP 5 | #define ORIGIN_ITERATOR_HPP 6 | 7 | #include 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /origin/iterator/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2009-2015 Andrew Sutton 2 | # All rights reserved 3 | 4 | include(GenerateExportHeader) 5 | 6 | # Set variables. 7 | 8 | # Add options. 9 | 10 | # Run platform checks. 11 | 12 | # Set compiler and linker flags. 13 | add_compiler_export_flags() 14 | 15 | # Add a library. 16 | add_library(origin-iterator STATIC 17 | core.cpp) 18 | 19 | target_compile_options(origin-iterator PUBLIC -std=c++1z -fconcepts) 20 | target_include_directories(origin-iterator 21 | PUBLIC "$") 22 | target_link_libraries(origin-iterator PUBLIC origin-core) 23 | 24 | add_dependencies(check origin-iterator) 25 | 26 | # Generate the configuration header. 27 | configure_file(config.hpp.in config.hpp) 28 | 29 | # Generate the export header. 30 | generate_export_header(origin-iterator EXPORT_FILE_NAME export.hpp) 31 | 32 | # Add subdirectories. 33 | add_subdirectory(core.test) 34 | 35 | # Add install targets. 36 | install( 37 | TARGETS origin-iterator 38 | EXPORT OriginTargets 39 | RUNTIME DESTINATION ${INSTALL_BIN_DIR} 40 | LIBRARY DESTINATION ${INSTALL_LIB_DIR} 41 | ARCHIVE DESTINATION ${INSTALL_LIB_DIR} 42 | INCLUDES DESTINATION ${INSTALL_INCLUDE_DIR} 43 | ) 44 | -------------------------------------------------------------------------------- /origin/iterator/config.hpp.in: -------------------------------------------------------------------------------- 1 | /** 2 | * @file origin/iterator/config.hpp 3 | * The configuration header for the Origin.Iterator library. 4 | * 5 | * @date 2015 6 | * @version @ORIGIN_VERSION@ 7 | */ 8 | 9 | /* config.hpp. Generated from config.hpp.in by cmake. */ 10 | 11 | #ifndef ORIGIN_ITERATOR_CONFIG_HPP 12 | #define ORIGIN_ITERATOR_CONFIG_HPP 13 | 14 | /* Name of package. */ 15 | #define ORIGIN_PACKAGE "@ORIGIN_PACKAGE_NAME@" 16 | 17 | /* Define to the full name of this package. */ 18 | #define ORIGIN_PACKAGE_NAME "@ORIGIN_PACKAGE_NAME@" 19 | 20 | /* Define to the one symbol short name of this package. */ 21 | #define ORIGIN_PACKAGE_TARNAME "@ORIGIN_PACKAGE_TARNAME@" 22 | 23 | /* Define to the version of this package. */ 24 | #define ORIGIN_PACKAGE_VERSION "@ORIGIN_PACKAGE_VERSION@" 25 | 26 | /* Define to the full name and version of this package. */ 27 | #define ORIGIN_PACKAGE_STRING "@ORIGIN_PACKAGE_STRING@" 28 | 29 | /* Define to the address where bug reports for this package should be sent. */ 30 | #define ORIGIN_PACKAGE_BUGREPORT "@ORIGIN_PACKAGE_BUGREPORT@" 31 | 32 | /* Define to the home page for this package. */ 33 | #define ORIGIN_PACKAGE_URL "@ORIGIN_PACKAGE_URL@" 34 | 35 | /* The version number of the Origin libraries. */ 36 | #define ORIGIN_VERSION "@ORIGIN_VERSION@" 37 | 38 | /* The major version of the Origin libraries. */ 39 | #define ORIGIN_VERSION_MAJOR @ORIGIN_VERSION_MAJOR@ 40 | 41 | /* The minor version of the Origin libraries. */ 42 | #define ORIGIN_VERSION_MINOR @ORIGIN_VERSION_MINOR@ 43 | 44 | /* The patch version of the Origin libraries. */ 45 | #define ORIGIN_VERSION_PATCH @ORIGIN_VERSION_PATCH@ 46 | 47 | /* The tweak version of the Origin libraries. */ 48 | #define ORIGIN_VERSION_TWEAK @ORIGIN_VERSION_TWEAK@ 49 | 50 | #include 51 | 52 | #endif // ORIGIN_ITERATOR_CONFIG_HPP 53 | -------------------------------------------------------------------------------- /origin/iterator/core.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include "core.hpp" 5 | -------------------------------------------------------------------------------- /origin/iterator/core.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #ifndef ORIGIN_ITERATOR_CORE_HPP 5 | #define ORIGIN_ITERATOR_CORE_HPP 6 | 7 | #include 8 | 9 | #include 10 | 11 | 12 | namespace origin { 13 | 14 | namespace iter_impl { 15 | 16 | 17 | template 18 | struct get_iterator_category; 19 | 20 | 21 | template 22 | struct get_iterator_category 23 | { 24 | using type = std::random_access_iterator_tag; 25 | }; 26 | 27 | 28 | template 29 | requires requires () { typename T::iterator_category; } 30 | struct get_iterator_category 31 | { 32 | using type = typename T::iterator_category; 33 | }; 34 | 35 | 36 | } // namespace iter_impl 37 | 38 | 39 | // The Iterator_category alias yields the category of a type 40 | // satisfying the Iterator concept. 41 | template 42 | using Iterator_category = typename iter_impl::get_iterator_category::type; 43 | 44 | 45 | // -------------------------------------------------------------------------- // 46 | // Iterator Concepts [iter.concept] 47 | 48 | // A type I is Readable if and only if it has an associated value type 49 | // that is accessible using unary * operator. 50 | template 51 | concept bool Readable() 52 | { 53 | return requires (I i) { {*i} -> const Value_type&; }; 54 | } 55 | 56 | 57 | // A type I is Writable if and only if the a value of type T can be 58 | // assigned through the unary * operator. 59 | template 60 | concept bool Writable() 61 | { 62 | return requires (I i, T x) { *i = std::forward(x); }; 63 | } 64 | 65 | 66 | // A type I is Permutable if and only if its associated value can be 67 | // replaced by moving. 68 | template 69 | concept bool Permutable() 70 | { 71 | return Readable() && Writable&&>(); 72 | } 73 | 74 | 75 | // A type I is mutable if and only if its associated value can be 76 | // replaced by moving. 77 | template 78 | concept bool Mutable() 79 | { 80 | return Permutable() && Writable&>(); 81 | } 82 | 83 | 84 | // Advanceable 85 | template 86 | concept bool Advanceable() 87 | { 88 | return requires (I i) { { ++i } -> I&; }; 89 | } 90 | 91 | 92 | // Incrementable 93 | template 94 | concept bool Incrementable() 95 | { 96 | return requires (I i) 97 | { 98 | typename Difference_type; 99 | {++i} -> I&; 100 | {i++} -> I; 101 | }; 102 | } 103 | 104 | 105 | // Iterator 106 | template 107 | concept bool Iterator() 108 | { 109 | return Equality_comparable() && requires(I i) 110 | { 111 | {++i} -> I&; 112 | {*i}; 113 | }; 114 | } 115 | 116 | 117 | // Input iterator 118 | template 119 | concept bool Input_iterator() 120 | { 121 | return Readable() && Advanceable(); 122 | } 123 | 124 | 125 | // Output iterator 126 | template 127 | concept bool Output_iterator() 128 | { 129 | return Writable() && Advanceable(); 130 | } 131 | 132 | 133 | // Forward iterator 134 | template 135 | concept bool Forward_iterator() 136 | { 137 | return Readable() && Incrementable() 138 | && Derived, std::forward_iterator_tag>(); 139 | } 140 | 141 | 142 | // Bidirectional iterator 143 | template 144 | concept bool Bidirectional_iterator() 145 | { 146 | return Forward_iterator() && requires (I i) 147 | { 148 | {--i} -> I&; 149 | {i--} -> I; 150 | }; 151 | } 152 | 153 | 154 | // Random access iterator 155 | template 156 | concept bool Random_access_iterator() { 157 | return Bidirectional_iterator() 158 | && requires (I i, I j, Difference_type n) 159 | { 160 | {i += n} -> I&; 161 | {i + n} -> I; 162 | {n + i} -> I; 163 | {i -= n} -> I&; 164 | {i - n} -> I; 165 | {i - j} -> Difference_type; 166 | {i[n]} -> decltype(*i); 167 | }; 168 | } 169 | 170 | 171 | } // namespace origin 172 | 173 | 174 | #endif 175 | -------------------------------------------------------------------------------- /origin/iterator/core.test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2009-2015 Andrew Sutton 2 | # All rights reserved 3 | 4 | link_libraries(origin-iterator) 5 | 6 | # Read/write categories 7 | add_run_test(iter_readable readable.cpp) 8 | add_run_test(iter_writable writable.cpp) 9 | add_run_test(iter_permutable permutable.cpp) 10 | add_run_test(iter_mutable mutable.cpp) 11 | 12 | # Basic traveral categories 13 | add_run_test(iter_advanceable advanceable.cpp) 14 | add_run_test(iter_incrementable incrementable.cpp) 15 | 16 | # Iterator categories 17 | add_run_test(iter_input_iterator input_iterator.cpp) 18 | add_run_test(iter_output_iterator output_iterator.cpp) 19 | add_run_test(iter_forward_iterator forward_iterator.cpp) 20 | add_run_test(iter_bidirectional_iterator bidirectional_iterator.cpp) 21 | add_run_test(iter_random_access_iterator random_access_iterator.cpp) 22 | 23 | # Associated type tests 24 | add_run_test(iter_value_type value_type.cpp) 25 | -------------------------------------------------------------------------------- /origin/iterator/core.test/advanceable.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | #include "test_iterator.hpp" 7 | 8 | // TODO: Write more tests 9 | 10 | static_assert(origin::Advanceable(), ""); 11 | 12 | int main() { } 13 | -------------------------------------------------------------------------------- /origin/iterator/core.test/bidirectional_iterator.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | 11 | using In = std::istream_iterator; 12 | using Out = std::ostream_iterator; 13 | using Fwd = std::forward_list; 14 | using List = std::list; 15 | using Vec = std::vector; 16 | 17 | static_assert(origin::Bidirectional_iterator(), ""); 18 | static_assert(origin::Bidirectional_iterator(), ""); 19 | static_assert(origin::Bidirectional_iterator(), ""); 20 | static_assert(origin::Bidirectional_iterator(), ""); 21 | static_assert(origin::Bidirectional_iterator(), ""); 22 | static_assert(origin::Bidirectional_iterator(), ""); 23 | 24 | static_assert(not origin::Bidirectional_iterator(), ""); 25 | static_assert(not origin::Bidirectional_iterator(), ""); 26 | static_assert(not origin::Bidirectional_iterator(), ""); 27 | static_assert(not origin::Bidirectional_iterator(), ""); 28 | 29 | int main() { } 30 | -------------------------------------------------------------------------------- /origin/iterator/core.test/forward_iterator.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | 11 | using In = std::istream_iterator; 12 | using Out = std::ostream_iterator; 13 | using Fwd = std::forward_list; 14 | using List = std::list; 15 | using Vec = std::vector; 16 | 17 | static_assert(origin::Forward_iterator(), ""); 18 | static_assert(origin::Forward_iterator(), ""); 19 | static_assert(origin::Forward_iterator(), ""); 20 | static_assert(origin::Forward_iterator(), ""); 21 | static_assert(origin::Forward_iterator(), ""); 22 | static_assert(origin::Forward_iterator(), ""); 23 | static_assert(origin::Forward_iterator(), ""); 24 | static_assert(origin::Forward_iterator(), ""); 25 | 26 | static_assert(not origin::Forward_iterator(), ""); 27 | static_assert(not origin::Forward_iterator(), ""); 28 | 29 | int main() { } 30 | -------------------------------------------------------------------------------- /origin/iterator/core.test/incrementable.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | #include "test_iterator.hpp" 7 | 8 | static_assert(origin::Incrementable(), ""); 9 | static_assert(not origin::Incrementable(), ""); 10 | 11 | int main() { } 12 | -------------------------------------------------------------------------------- /origin/iterator/core.test/input_iterator.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | using In = std::istream_iterator; 11 | using Out = std::ostream_iterator; 12 | using Fwd = std::forward_list; 13 | using List = std::list; 14 | using Vec = std::vector; 15 | 16 | static_assert(origin::Input_iterator(), ""); 17 | static_assert(origin::Input_iterator(), ""); 18 | static_assert(origin::Input_iterator(), ""); 19 | static_assert(origin::Input_iterator(), ""); 20 | static_assert(origin::Input_iterator(), ""); 21 | static_assert(origin::Input_iterator(), ""); 22 | static_assert(origin::Input_iterator(), ""); 23 | static_assert(origin::Input_iterator(), ""); 24 | static_assert(origin::Input_iterator(), ""); 25 | 26 | static_assert(not origin::Input_iterator(), ""); 27 | 28 | int main() { } 29 | -------------------------------------------------------------------------------- /origin/iterator/core.test/mutable.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | #include "test_resource.hpp" 7 | 8 | static_assert(origin::Mutable(), ""); 9 | static_assert(! origin::Mutable(), ""); 10 | 11 | int main() { } 12 | -------------------------------------------------------------------------------- /origin/iterator/core.test/output_iterator.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | 11 | using In = std::istream_iterator; 12 | using Out = std::ostream_iterator; 13 | using Fwd = std::forward_list; 14 | using List = std::list; 15 | using Vec = std::vector; 16 | 17 | static_assert(origin::Output_iterator(), ""); 18 | static_assert(origin::Output_iterator(), ""); 19 | static_assert(origin::Output_iterator(), ""); 20 | static_assert(origin::Output_iterator(), ""); 21 | static_assert(origin::Output_iterator(), ""); 22 | 23 | static_assert(not origin::Output_iterator(), ""); 24 | static_assert(not origin::Output_iterator(), ""); 25 | static_assert(not origin::Output_iterator(), ""); 26 | static_assert(not origin::Output_iterator(), ""); 27 | static_assert(not origin::Output_iterator(), ""); 28 | 29 | int main() { } 30 | -------------------------------------------------------------------------------- /origin/iterator/core.test/permutable.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | #include "test_resource.hpp" 7 | 8 | static_assert(origin::Permutable(), ""); 9 | static_assert(origin::Permutable(), ""); 10 | 11 | int main() { } 12 | -------------------------------------------------------------------------------- /origin/iterator/core.test/random_access_iterator.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | 11 | using In = std::istream_iterator; 12 | using Out = std::ostream_iterator; 13 | using Fwd = std::forward_list; 14 | using List = std::list; 15 | using Vec = std::vector; 16 | 17 | static_assert(origin::Random_access_iterator(), ""); 18 | static_assert(origin::Random_access_iterator(), ""); 19 | static_assert(origin::Random_access_iterator(), ""); 20 | static_assert(origin::Random_access_iterator(), ""); 21 | 22 | static_assert(!origin::Random_access_iterator(), ""); 23 | static_assert(!origin::Random_access_iterator(), ""); 24 | static_assert(!origin::Random_access_iterator(), ""); 25 | static_assert(!origin::Random_access_iterator(), ""); 26 | static_assert(!origin::Random_access_iterator(), ""); 27 | static_assert(!origin::Random_access_iterator(), ""); 28 | 29 | int main() { } 30 | -------------------------------------------------------------------------------- /origin/iterator/core.test/readable.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | static_assert(origin::Readable(), ""); 7 | static_assert(origin::Readable(), ""); 8 | static_assert(origin::Readable(), ""); 9 | static_assert(origin::Readable(), ""); 10 | 11 | int main() { } 12 | -------------------------------------------------------------------------------- /origin/iterator/core.test/test_iterator.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #ifndef TEST_ITERATOR_HPP 5 | #define TEST_ITERATOR_HPP 6 | 7 | // A simple input iterator model. 8 | struct input_iter 9 | { 10 | input_iter& operator++() { return *this; } 11 | }; 12 | 13 | bool operator==(input_iter, input_iter) { return true; } 14 | bool operator!=(input_iter, input_iter) { return true; } 15 | 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /origin/iterator/core.test/test_resource.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #ifndef TEST_RESOURCE_HPP 5 | #define TEST_RESOURCE_HPP 6 | 7 | // A move-only type 8 | struct res 9 | { 10 | res(res&&) = default; 11 | res& operator=(res&&) = default; 12 | 13 | res(const res&) = delete; 14 | res& operator=(const res&) = delete; 15 | }; 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /origin/iterator/core.test/value_type.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | 11 | // True when the range R has size type T. 12 | template 13 | constexpr bool Has_value_type() 14 | { 15 | return origin::Same, T>(); 16 | } 17 | 18 | using Fwd = std::forward_list; 19 | using List = std::list; 20 | using Vec = std::vector; 21 | 22 | static_assert(Has_value_type(), ""); 23 | static_assert(Has_value_type(), ""); 24 | static_assert(Has_value_type(), ""); 25 | static_assert(Has_value_type(), ""); 26 | 27 | int main() { } 28 | -------------------------------------------------------------------------------- /origin/iterator/core.test/writable.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | static_assert(origin::Writable(), ""); 7 | static_assert(origin::Writable(), ""); 8 | static_assert(origin::Writable(), ""); 9 | 10 | int main() { } 11 | -------------------------------------------------------------------------------- /origin/memory.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #ifndef ORIGIN_RANGES 5 | #define ORIGIN_RANGES 6 | 7 | // Support for allocators. 8 | #include 9 | 10 | // Generic construct/destroy. 11 | #include 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /origin/memory/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2009-2015 Andrew Sutton 2 | # All rights reserved 3 | 4 | include(GenerateExportHeader) 5 | 6 | # Set variables. 7 | 8 | # Add options. 9 | 10 | # Run platform checks. 11 | 12 | # Set compiler and linker flags. 13 | add_compiler_export_flags() 14 | 15 | # Add a library. 16 | add_library(origin-memory STATIC 17 | memory.cpp 18 | allocator.cpp) 19 | 20 | target_compile_options(origin-memory PUBLIC -std=c++1z -fconcepts) 21 | target_include_directories(origin-memory 22 | PUBLIC "$") 23 | target_link_libraries(origin-memory PUBLIC origin-core) 24 | 25 | add_dependencies(check origin-memory) 26 | 27 | # Generate the configuration header. 28 | configure_file(config.hpp.in config.hpp) 29 | 30 | # Generate the export header. 31 | generate_export_header(origin-memory EXPORT_FILE_NAME export.hpp) 32 | 33 | # Add subdirectories. 34 | 35 | # Add install targets. 36 | install( 37 | TARGETS origin-memory 38 | EXPORT OriginTargets 39 | RUNTIME DESTINATION ${INSTALL_BIN_DIR} 40 | LIBRARY DESTINATION ${INSTALL_LIB_DIR} 41 | ARCHIVE DESTINATION ${INSTALL_LIB_DIR} 42 | INCLUDES DESTINATION ${INSTALL_INCLUDE_DIR} 43 | ) 44 | -------------------------------------------------------------------------------- /origin/memory/allocator.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include "allocator.hpp" 5 | 6 | namespace origin 7 | { 8 | 9 | namespace 10 | { 11 | 12 | // The global default allocator. 13 | allocator alloc_; 14 | 15 | } // namespace 16 | 17 | 18 | // Returns the default allocator. 19 | allocator& 20 | default_allocator() 21 | { 22 | return alloc_; 23 | } 24 | 25 | 26 | } // namespace origin 27 | -------------------------------------------------------------------------------- /origin/memory/allocator.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #ifndef ORIGIN_MEMORY_ALLOCATOR_HPP 5 | #define ORIGIN_MEMORY_ALLOCATOR_HPP 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | namespace origin 13 | { 14 | 15 | 16 | // ---------------------------------------------------------------------------// 17 | // Allocator concepts [mem.alloc] 18 | // 19 | // TODO: There is a concept of a non-deallocating allocator. 20 | // Should that be separate, or should deallocate() just be 21 | // a no-op. 22 | 23 | 24 | // The allocator concept defines the required properties of 25 | // a facility that can allocate and deallocate memory. 26 | template 27 | concept bool Allocator() 28 | { 29 | return requires (A a, int n, void* p) 30 | { 31 | { a.allocate(n) } -> void*; 32 | { a.deallocate(p) }; 33 | }; 34 | } 35 | 36 | 37 | // ---------------------------------------------------------------------------// 38 | // Default allocator [mem.alloc.default] 39 | 40 | // An allocator is a resource type that is responsible for the acquisition 41 | // and release of memory. It is an abstract base class. 42 | // 43 | // TODO: Write better docs. 44 | // 45 | // TODO: Look at recent allocator specifications to determine what 46 | // sets of operations are actually being required. 47 | struct allocator 48 | { 49 | virtual ~allocator() { } 50 | virtual void* allocate(int); 51 | virtual void deallocate(void*, int); 52 | }; 53 | 54 | 55 | inline void* 56 | allocator::allocate(int n) 57 | { 58 | return ::operator new(n); 59 | } 60 | 61 | 62 | inline void 63 | allocator::deallocate(void* p, int) 64 | { 65 | ::operator delete(p); 66 | } 67 | 68 | 69 | allocator& default_allocator(); 70 | 71 | 72 | // ---------------------------------------------------------------------------// 73 | // Adaptors [mem.alloc.default] 74 | 75 | 76 | // The std allocator is a wrapper around an origin Allocator 77 | // tha satisfies the requirements of a standard allocator. 78 | template 79 | struct std_allocator 80 | { 81 | using value_type = T; 82 | using pointer = T*; 83 | using const_pointer = T const*; 84 | using reference = T&; 85 | using const_reference = const T&; 86 | using size_type = unsigned; 87 | using difference_type = int; 88 | 89 | using propagate_on_container_move_assignment = std::true_type; 90 | 91 | template 92 | using rebind = std_allocator; 93 | 94 | static T* address(T&); 95 | static T const* address(T const&); 96 | 97 | T* allocate(int, void* = nullptr); 98 | void deallocate(void*, int); 99 | 100 | static int max_size(); 101 | 102 | template 103 | requires Constructible() 104 | static void construct(T*, Args&&...); 105 | 106 | template 107 | static void destroy(U*); 108 | 109 | A* alloc_; 110 | }; 111 | 112 | 113 | template 114 | inline T* 115 | std_allocator::address(T& t) 116 | { 117 | return std::addressof(t); 118 | } 119 | 120 | 121 | template 122 | inline T const* 123 | std_allocator::address(T const& t) 124 | { 125 | return std::addressof(t); 126 | } 127 | 128 | 129 | template 130 | inline T* 131 | std_allocator::allocate(int n, void* hint) 132 | { 133 | return reinterpret_cast(alloc_->allocate(n * sizeof(T), hint)); 134 | } 135 | 136 | 137 | template 138 | inline void 139 | std_allocator::deallocate(void* p, int n) 140 | { 141 | alloc_->deallocate(p, n); 142 | } 143 | 144 | 145 | template 146 | inline int 147 | std_allocator::max_size() 148 | { 149 | return INT_MAX / sizeof(T); 150 | } 151 | 152 | 153 | template 154 | template 155 | requires Constructible() 156 | inline void 157 | std_allocator::construct(T* p, Args&&... args) 158 | { 159 | ::new (p) T(std::forward(args)...); 160 | } 161 | 162 | 163 | template 164 | template 165 | inline void 166 | std_allocator::destroy(U* p) 167 | { 168 | p->~U(); 169 | } 170 | 171 | 172 | 173 | } // namespace 174 | 175 | 176 | #endif 177 | -------------------------------------------------------------------------------- /origin/memory/config.hpp.in: -------------------------------------------------------------------------------- 1 | /** 2 | * @file origin/memory/config.hpp 3 | * The configuration header for the Origin.Memory library. 4 | * 5 | * @date 2015 6 | * @version @ORIGIN_VERSION@ 7 | */ 8 | 9 | /* config.hpp. Generated from config.hpp.in by cmake. */ 10 | 11 | #ifndef ORIGIN_MEMORY_CONFIG_HPP 12 | #define ORIGIN_MEMORY_CONFIG_HPP 13 | 14 | /* Name of package. */ 15 | #define ORIGIN_PACKAGE "@ORIGIN_PACKAGE_NAME@" 16 | 17 | /* Define to the full name of this package. */ 18 | #define ORIGIN_PACKAGE_NAME "@ORIGIN_PACKAGE_NAME@" 19 | 20 | /* Define to the one symbol short name of this package. */ 21 | #define ORIGIN_PACKAGE_TARNAME "@ORIGIN_PACKAGE_TARNAME@" 22 | 23 | /* Define to the version of this package. */ 24 | #define ORIGIN_PACKAGE_VERSION "@ORIGIN_PACKAGE_VERSION@" 25 | 26 | /* Define to the full name and version of this package. */ 27 | #define ORIGIN_PACKAGE_STRING "@ORIGIN_PACKAGE_STRING@" 28 | 29 | /* Define to the address where bug reports for this package should be sent. */ 30 | #define ORIGIN_PACKAGE_BUGREPORT "@ORIGIN_PACKAGE_BUGREPORT@" 31 | 32 | /* Define to the home page for this package. */ 33 | #define ORIGIN_PACKAGE_URL "@ORIGIN_PACKAGE_URL@" 34 | 35 | /* The version number of the Origin libraries. */ 36 | #define ORIGIN_VERSION "@ORIGIN_VERSION@" 37 | 38 | /* The major version of the Origin libraries. */ 39 | #define ORIGIN_VERSION_MAJOR @ORIGIN_VERSION_MAJOR@ 40 | 41 | /* The minor version of the Origin libraries. */ 42 | #define ORIGIN_VERSION_MINOR @ORIGIN_VERSION_MINOR@ 43 | 44 | /* The patch version of the Origin libraries. */ 45 | #define ORIGIN_VERSION_PATCH @ORIGIN_VERSION_PATCH@ 46 | 47 | /* The tweak version of the Origin libraries. */ 48 | #define ORIGIN_VERSION_TWEAK @ORIGIN_VERSION_TWEAK@ 49 | 50 | #include 51 | 52 | #endif // ORIGIN_MEMORY_CONFIG_HPP 53 | -------------------------------------------------------------------------------- /origin/memory/memory.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include "memory.hpp" 5 | -------------------------------------------------------------------------------- /origin/memory/memory.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #ifndef ORIGIN_MEMORY_MEMORY_HPP 5 | #define ORIGIN_MEMORY_MEMORY_HPP 6 | 7 | #include 8 | 9 | 10 | namespace origin 11 | { 12 | 13 | 14 | // Construct an object of type `T` at address `p` with the given 15 | // arguments. Note that this does not allocate the memory where the 16 | // object is constructed. 17 | // 18 | // Behavior is undefined if insufficient memory has not been allocated 19 | // for the given object. 20 | template 21 | requires Constructible() 22 | inline void 23 | construct(T* p, Args&&... args) 24 | { 25 | return new(p) T(std::forward(args)...); 26 | } 27 | 28 | 29 | // Destroy an object of type `T` at the address `p`. Note that this 30 | // does not release the memory of stored object. 31 | template 32 | inline void 33 | destroy(T* p) 34 | { 35 | p->~T(); 36 | } 37 | 38 | 39 | } // namespace origin 40 | 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /origin/numeric/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2009-2015 Andrew Sutton 2 | # All rights reserved 3 | 4 | include(GenerateExportHeader) 5 | 6 | # Set variables. 7 | 8 | # Add options. 9 | 10 | # Run platform checks. 11 | 12 | # Set compiler and linker flags. 13 | add_compiler_export_flags() 14 | 15 | # Add a library. 16 | add_library(origin-numeric STATIC 17 | numeric.cpp 18 | algebra.cpp) 19 | 20 | target_compile_options(origin-numeric PUBLIC -std=c++1z -fconcepts) 21 | target_include_directories(origin-numeric 22 | PUBLIC "$") 23 | target_link_libraries(origin-numeric PUBLIC origin-core) 24 | 25 | add_dependencies(check origin-numeric) 26 | 27 | # Generate the configuration header. 28 | configure_file(config.hpp.in config.hpp) 29 | 30 | # Generate the export header. 31 | generate_export_header(origin-numeric EXPORT_FILE_NAME export.hpp) 32 | 33 | # Add subdirectories. 34 | add_subdirectory(algebra.test) 35 | 36 | # Add install targets. 37 | install( 38 | TARGETS origin-numeric 39 | EXPORT OriginTargets 40 | RUNTIME DESTINATION ${INSTALL_BIN_DIR} 41 | LIBRARY DESTINATION ${INSTALL_LIB_DIR} 42 | ARCHIVE DESTINATION ${INSTALL_LIB_DIR} 43 | INCLUDES DESTINATION ${INSTALL_INCLUDE_DIR} 44 | ) 45 | -------------------------------------------------------------------------------- /origin/numeric/algebra.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include "algebra.hpp" 5 | -------------------------------------------------------------------------------- /origin/numeric/algebra.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #ifndef ORIGIN_NUMERIC_ALGEBRA_HPP 5 | #define ORIGIN_NUMERIC_ALGEBRA_HPP 6 | 7 | #include 8 | #include 9 | 10 | namespace origin { 11 | 12 | // A monoid is a set of values equipped with an associative binary 13 | // operation and some identity element. 14 | template 15 | concept bool Monoid() { 16 | return Binary_operation(); 17 | } 18 | 19 | 20 | // The left fold operation. 21 | template 22 | requires Monoid, Op>() 23 | Value_type 24 | foldl(I first, I last, Op op, const Value_type& e) { 25 | Value_type x = e; 26 | while (first != last) { 27 | x = op(x, *first); 28 | ++first; 29 | } 30 | return x; 31 | } 32 | 33 | 34 | // The right fold operation. 35 | template 36 | requires Monoid, Op>() 37 | Value_type 38 | foldr(I first, I last, Op op) { 39 | using R = std::reverse_iterator; 40 | return foldl(R{last}, R{first}, op); 41 | } 42 | 43 | 44 | // -------------------------------------------------------------------------- // 45 | // Monoid structure [monoid.struct] // 46 | 47 | // The monoid algebraic structure is used to encapsulate operators 48 | // end their identity functions. A number of constructors are provided 49 | // for common abstractions. 50 | template 51 | requires Monoid() 52 | struct monoid { 53 | T id; 54 | Op op; 55 | }; 56 | 57 | 58 | // Left-fold with a monoid structure. 59 | template 60 | inline Value_type 61 | foldl(I first, I last, monoid, Op> const& m) { 62 | return foldl(first, last, m.op, m.id); 63 | } 64 | 65 | // Right-fold with a monoid structure. 66 | template 67 | inline Value_type 68 | foldr(I first, I last, monoid, Op> const& m) { 69 | return foldr(first, last, m.op, m.id); 70 | } 71 | 72 | 73 | // -------------------------------------------------------------------------- // 74 | // Monoid constructors [monoid.ctor] // 75 | // 76 | // The following functions are used to construct instances of 77 | // monoids for different types. 78 | // 79 | // Each of the following constructs a monoid for its corresponding 80 | // operations. 81 | // 82 | // 83 | // Sum() addition 84 | // Product() multiplication 85 | // All() intersection 86 | // Any() union 87 | // 88 | // Note that 89 | // 90 | // Each constructor above also accepts the identity element, when 91 | // there is no direct association of the identity with the 92 | // type (e.g., matrices of dynamic bound). 93 | // 94 | // Sum(e) 95 | // Product(e) 96 | // All(e) 97 | // Any(e) 98 | // 99 | // These functions are capitalized to emphasize the idea that they 100 | // construct unspecified models of a concept. 101 | // 102 | // NOTE: In the following declarations, the defaulted operators 103 | // are not part of the public interface. 104 | 105 | namespace monoid_impl { 106 | 107 | template 108 | struct all_any_traits { 109 | using all_op = std::bit_and; 110 | using any_op = std::bit_or; 111 | static constexpr T all_id = -1; 112 | static constexpr T any_id = 0; 113 | }; 114 | 115 | template<> 116 | struct all_any_traits { 117 | using all_op = std::logical_and; 118 | using any_op = std::logical_or; 119 | static constexpr bool all_id = true; 120 | static constexpr bool any_id = false; 121 | }; 122 | 123 | template 124 | using all_op = typename all_any_traits::all_op; 125 | 126 | template 127 | using any_op = typename all_any_traits::any_op; 128 | 129 | template 130 | static constexpr T all_id() { return all_any_traits::all_id; } 131 | 132 | template 133 | static constexpr T any_id() { return all_any_traits::any_id; } 134 | 135 | } // namespace monoid_impl 136 | 137 | // -------------------------------------------------------------------------- // 138 | // Sum [monoid.sum] // 139 | // 140 | // The Sum constructor defines a monoid (T, +) where T is an 141 | // arithmetic type. 142 | 143 | template> 144 | inline monoid 145 | Sum() { return monoid{T{0}, Op{}}; } 146 | 147 | template> 148 | requires Monoid() 149 | inline monoid 150 | Sum(T const& e) { return monoid{e, Op{}}; } 151 | 152 | 153 | // -------------------------------------------------------------------------- // 154 | // Product [monoid.product] // 155 | 156 | template> 157 | inline monoid 158 | Product() { return monoid{T{1}, Op{}}; } 159 | 160 | template> 161 | requires Monoid() 162 | inline monoid 163 | Product(T const& e) { return monoid{e, Op{}}; } 164 | 165 | 166 | // -------------------------------------------------------------------------- // 167 | // All [monoid.all] // 168 | // 169 | // The All constructor defines the algebraic structure (T, op) where 170 | // op is defined as follows: 171 | // 172 | // - if T has type bool, op is the logical and operator and the 173 | // identity element is true; 174 | // - otherwise, if T is some other integral type, it is the bitwise 175 | // and operator and the identity element is -1. 176 | // 177 | // In general, the semantics of the operator in this monoid can be 178 | // thought of as computing the intersection of sets. When used in 179 | // a fold, the result is a set containing the common elements of 180 | // the operand. 181 | // 182 | // TODO: Can we extend this for set-like data structures? 183 | 184 | template> 185 | inline monoid 186 | All() { return monoid{monoid_impl::all_id(), Op{}}; } 187 | 188 | template 189 | requires Monoid() 190 | inline monoid 191 | All(T const& e) { return monoid{e, Op{}}; } 192 | 193 | 194 | // -------------------------------------------------------------------------- // 195 | // Any [monoid.any] // 196 | // 197 | // The Any constructor defines the algebraic structure (T, op) where 198 | // op is defined as follows: 199 | // 200 | // - if T has type bool, op is the logical or operator and the 201 | // identity element is false; 202 | // - otherwise, if T is some other integral type, it is the bitwise 203 | // or operator and the identity element is 0. 204 | // 205 | // In general, the semantics of the operator in this monoid can be 206 | // thought of as computing the union of sets. 207 | 208 | template> 209 | inline monoid 210 | Any() { return monoid{monoid_impl::any_id(), Op{}}; } 211 | 212 | template 213 | requires Monoid() 214 | inline monoid 215 | Any(T const& e) { return monoid{e, Op{}}; } 216 | 217 | 218 | } // namespace origin 219 | 220 | #endif 221 | -------------------------------------------------------------------------------- /origin/numeric/algebra.test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2009-2015 Andrew Sutton 2 | # All rights reserved 3 | 4 | link_libraries(origin-numeric) 5 | 6 | add_run_test(algebra_foldl foldl.cpp) 7 | -------------------------------------------------------------------------------- /origin/numeric/algebra.test/foldl.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | using namespace origin; 10 | 11 | int main() { 12 | int a[] {1, 2, 3}; 13 | assert(foldl(a, a + 3, std::plus{}, 0) == 6); 14 | assert(foldl(a, a + 3, Sum()) == 6); 15 | assert(foldl(a, a + 3, Product()) == 6); 16 | 17 | 18 | bool b1[] {true, true, true}; 19 | bool b2[] {false, false, true}; 20 | assert(foldl(b1, b1 + 3, All<>()) == true); 21 | assert(foldl(b1, b1 + 3, Any<>()) == true); 22 | } 23 | -------------------------------------------------------------------------------- /origin/numeric/config.hpp.in: -------------------------------------------------------------------------------- 1 | /** 2 | * @file origin/numeric/config.hpp 3 | * The configuration header for the Origin.Numeric library. 4 | * 5 | * @date 2015 6 | * @version @ORIGIN_VERSION@ 7 | */ 8 | 9 | /* config.hpp. Generated from config.hpp.in by cmake. */ 10 | 11 | #ifndef ORIGIN_NUMERIC_CONFIG_HPP 12 | #define ORIGIN_NUMERIC_CONFIG_HPP 13 | 14 | /* Name of package. */ 15 | #define ORIGIN_PACKAGE "@ORIGIN_PACKAGE_NAME@" 16 | 17 | /* Define to the full name of this package. */ 18 | #define ORIGIN_PACKAGE_NAME "@ORIGIN_PACKAGE_NAME@" 19 | 20 | /* Define to the one symbol short name of this package. */ 21 | #define ORIGIN_PACKAGE_TARNAME "@ORIGIN_PACKAGE_TARNAME@" 22 | 23 | /* Define to the version of this package. */ 24 | #define ORIGIN_PACKAGE_VERSION "@ORIGIN_PACKAGE_VERSION@" 25 | 26 | /* Define to the full name and version of this package. */ 27 | #define ORIGIN_PACKAGE_STRING "@ORIGIN_PACKAGE_STRING@" 28 | 29 | /* Define to the address where bug reports for this package should be sent. */ 30 | #define ORIGIN_PACKAGE_BUGREPORT "@ORIGIN_PACKAGE_BUGREPORT@" 31 | 32 | /* Define to the home page for this package. */ 33 | #define ORIGIN_PACKAGE_URL "@ORIGIN_PACKAGE_URL@" 34 | 35 | /* The version number of the Origin libraries. */ 36 | #define ORIGIN_VERSION "@ORIGIN_VERSION@" 37 | 38 | /* The major version of the Origin libraries. */ 39 | #define ORIGIN_VERSION_MAJOR @ORIGIN_VERSION_MAJOR@ 40 | 41 | /* The minor version of the Origin libraries. */ 42 | #define ORIGIN_VERSION_MINOR @ORIGIN_VERSION_MINOR@ 43 | 44 | /* The patch version of the Origin libraries. */ 45 | #define ORIGIN_VERSION_PATCH @ORIGIN_VERSION_PATCH@ 46 | 47 | /* The tweak version of the Origin libraries. */ 48 | #define ORIGIN_VERSION_TWEAK @ORIGIN_VERSION_TWEAK@ 49 | 50 | #include 51 | 52 | #endif // ORIGIN_NUMERIC_CONFIG_HPP 53 | -------------------------------------------------------------------------------- /origin/numeric/numeric.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include "numeric.hpp" 5 | -------------------------------------------------------------------------------- /origin/numeric/numeric.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #ifndef ORIGIN_NUMERIC_HPP 5 | #define ORIGIN_NUMERIC_HPP 6 | 7 | // This module defines the entirety of the Origin Numeric library, which 8 | // includes numeric and algebraic concepts and their models. 9 | // 10 | // TODO: There are a lot of interesting things that this library could 11 | // use: an arbitrary precision integer library, a library of statically 12 | // bound fixed-precision integer types (e.g., Boost.Multiprecision), 13 | // dynamically bound fixed-precision integer types, fractions and rational 14 | // numbers, etc. 15 | 16 | #include 17 | #include 18 | 19 | namespace origin { 20 | 21 | // -------------------------------------------------------------------------- // 22 | // Numbers [num] // 23 | // 24 | // A number is a mathematical object that represents some quantity. 25 | 26 | 27 | // The Number concept defines the abstract notion of a number. 28 | // 29 | // FIXME: This does not allow 30 | template 31 | concept bool Number() { return std::is_arithmetic::value; } 32 | 33 | 34 | } // namespace origin 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /origin/origin.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | -------------------------------------------------------------------------------- /origin/range.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #ifndef ORIGIN_RANGE_HPP 5 | #define ORIGIN_RANGE_HPP 6 | 7 | // Range concepts. 8 | #include 9 | 10 | // Basic range abstractions. 11 | #include 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /origin/range/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2009-2015 Andrew Sutton 2 | # All rights reserved 3 | 4 | include(GenerateExportHeader) 5 | 6 | # Set variables. 7 | 8 | # Add options. 9 | 10 | # Run platform checks. 11 | 12 | # Set compiler and linker flags. 13 | add_compiler_export_flags() 14 | 15 | # Add a library. 16 | add_library(origin-range STATIC 17 | core.cpp 18 | range.cpp) 19 | 20 | target_compile_options(origin-range PUBLIC -std=c++1z -fconcepts) 21 | target_include_directories(origin-range 22 | PUBLIC "$") 23 | target_link_libraries(origin-range PUBLIC origin-iterator) 24 | 25 | add_dependencies(check origin-range) 26 | 27 | # Generate the configuration header. 28 | configure_file(config.hpp.in config.hpp) 29 | 30 | # Generate the export header. 31 | generate_export_header(origin-range EXPORT_FILE_NAME export.hpp) 32 | 33 | # Add subdirectories. 34 | add_subdirectory(core.test) 35 | add_subdirectory(range.test) 36 | 37 | # Add install targets. 38 | install( 39 | TARGETS origin-range 40 | EXPORT OriginTargets 41 | RUNTIME DESTINATION ${INSTALL_BIN_DIR} 42 | LIBRARY DESTINATION ${INSTALL_LIB_DIR} 43 | ARCHIVE DESTINATION ${INSTALL_LIB_DIR} 44 | INCLUDES DESTINATION ${INSTALL_INCLUDE_DIR} 45 | ) 46 | -------------------------------------------------------------------------------- /origin/range/config.hpp.in: -------------------------------------------------------------------------------- 1 | /** 2 | * @file origin/range/config.hpp 3 | * The configuration header for the Origin.Range library. 4 | * 5 | * @date 2015 6 | * @version @ORIGIN_VERSION@ 7 | */ 8 | 9 | /* config.hpp. Generated from config.hpp.in by cmake. */ 10 | 11 | #ifndef ORIGIN_RANGE_CONFIG_HPP 12 | #define ORIGIN_RANGE_CONFIG_HPP 13 | 14 | /* Name of package. */ 15 | #define ORIGIN_PACKAGE "@ORIGIN_PACKAGE_NAME@" 16 | 17 | /* Define to the full name of this package. */ 18 | #define ORIGIN_PACKAGE_NAME "@ORIGIN_PACKAGE_NAME@" 19 | 20 | /* Define to the one symbol short name of this package. */ 21 | #define ORIGIN_PACKAGE_TARNAME "@ORIGIN_PACKAGE_TARNAME@" 22 | 23 | /* Define to the version of this package. */ 24 | #define ORIGIN_PACKAGE_VERSION "@ORIGIN_PACKAGE_VERSION@" 25 | 26 | /* Define to the full name and version of this package. */ 27 | #define ORIGIN_PACKAGE_STRING "@ORIGIN_PACKAGE_STRING@" 28 | 29 | /* Define to the address where bug reports for this package should be sent. */ 30 | #define ORIGIN_PACKAGE_BUGREPORT "@ORIGIN_PACKAGE_BUGREPORT@" 31 | 32 | /* Define to the home page for this package. */ 33 | #define ORIGIN_PACKAGE_URL "@ORIGIN_PACKAGE_URL@" 34 | 35 | /* The version number of the Origin libraries. */ 36 | #define ORIGIN_VERSION "@ORIGIN_VERSION@" 37 | 38 | /* The major version of the Origin libraries. */ 39 | #define ORIGIN_VERSION_MAJOR @ORIGIN_VERSION_MAJOR@ 40 | 41 | /* The minor version of the Origin libraries. */ 42 | #define ORIGIN_VERSION_MINOR @ORIGIN_VERSION_MINOR@ 43 | 44 | /* The patch version of the Origin libraries. */ 45 | #define ORIGIN_VERSION_PATCH @ORIGIN_VERSION_PATCH@ 46 | 47 | /* The tweak version of the Origin libraries. */ 48 | #define ORIGIN_VERSION_TWEAK @ORIGIN_VERSION_TWEAK@ 49 | 50 | #include 51 | 52 | #endif // ORIGIN_RANGE_CONFIG_HPP 53 | -------------------------------------------------------------------------------- /origin/range/core.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include "core.hpp" 5 | -------------------------------------------------------------------------------- /origin/range/core.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #ifndef ORIGIN_RANGE_CORE_HPP 5 | #define ORIGIN_RANGE_CORE_HPP 6 | 7 | #include 8 | 9 | #include 10 | 11 | 12 | namespace origin 13 | { 14 | 15 | // -------------------------------------------------------------------------- // 16 | // Range Sentinel [range.sentinel] 17 | 18 | 19 | // A type is a Sentinel for an Iterator if and only if it is Copyable 20 | // and can be compared for equality with iterator. 21 | template 22 | concept bool Sentinel() 23 | { 24 | return Copyable() && Equality_comparable(); 25 | } 26 | 27 | 28 | // -------------------------------------------------------------------------- // 29 | // Range Concepts [range.concept] 30 | 31 | // NOTE: The iterator and sentinel types are deduced against R& instead 32 | // of just R because of unintended decay for array types. In other words, 33 | // these aliases will fail when they should not. 34 | 35 | 36 | // The Iterator_type function returns the iterator type of a Range, the 37 | // type resulting from a call to std::begin. 38 | template 39 | using Iterator_type = decltype(std::begin(std::declval())); 40 | 41 | 42 | // The Sentinel type function returns the sentinel type of a Range, the 43 | // type resuluting from a call to std::end. Note that this is not 44 | // required to be the same as a Range's Iterator_type. 45 | template 46 | using Sentinel_type = decltype(std::end(std::declval())); 47 | 48 | 49 | namespace seq_impl 50 | { 51 | 52 | // Bring these into scope so the concept can find them 53 | // the without qualification. 54 | using std::begin; 55 | using std::end; 56 | 57 | 58 | template 59 | concept bool Range() 60 | { 61 | return requires (R& range) 62 | { 63 | typename Iterator_type; 64 | typename Sentinel_type; 65 | { begin(range) } -> Iterator_type; 66 | { end(range) } -> Sentinel_type; 67 | }; 68 | } 69 | 70 | } // namespace range_impl 71 | 72 | 73 | // A range is a sequence of elements denoted by a pair of iterators, 74 | // accessed using using std::begin() and std::end(). 75 | // 76 | // BUG: The requirements for Iterator and Sentinel should be nested 77 | // requirements, but as of 13.04.2014, they cause an ICE. 78 | template 79 | concept bool 80 | Range() 81 | { 82 | return seq_impl::Range(); 83 | } 84 | 85 | 86 | // Input_range 87 | template 88 | concept bool 89 | Input_range() 90 | { 91 | return Range() && Input_iterator>(); 92 | } 93 | 94 | 95 | // Output_range 96 | template 97 | concept bool 98 | Output_range() 99 | { 100 | return Range() && Output_iterator, T>(); 101 | } 102 | 103 | 104 | // Forward_range 105 | template 106 | concept bool 107 | Forward_range() 108 | { 109 | return Range() && Forward_iterator>(); 110 | } 111 | 112 | 113 | // Bidirectional_range 114 | template 115 | concept bool 116 | Bidirectional_range() 117 | { 118 | return Range() && Bidirectional_iterator>(); 119 | } 120 | 121 | 122 | // Random_access_range 123 | template 124 | concept bool 125 | Random_access_range() 126 | { 127 | return Range() && Random_access_iterator>(); 128 | } 129 | 130 | 131 | } // namespace origin 132 | 133 | 134 | #endif -------------------------------------------------------------------------------- /origin/range/core.test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2009-2015 Andrew Sutton 2 | # All rights reserved 3 | 4 | link_libraries(origin-range) 5 | 6 | add_run_test(range_iterator_type iterator_type.cpp) 7 | add_run_test(range_sentinel_type sentinel_type.cpp) 8 | 9 | add_run_test(range_range range.cpp) 10 | add_run_test(range_input_range input_range.cpp) 11 | add_run_test(range_output_range output_range.cpp) 12 | add_run_test(range_forward_range forward_range.cpp) 13 | add_run_test(range_bidirectional_range bidirectional_range.cpp) 14 | add_run_test(range_random_access_range random_access_range.cpp) 15 | 16 | add_run_test(range_size_type size_type.cpp) 17 | add_run_test(range_value_type value_type.cpp) 18 | -------------------------------------------------------------------------------- /origin/range/core.test/bidirectional_range.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | using Fwd = std::forward_list; 11 | using List = std::list; 12 | using Vec = std::vector; 13 | 14 | static_assert(origin::Bidirectional_range(), ""); 15 | static_assert(origin::Bidirectional_range(), ""); 16 | static_assert(origin::Bidirectional_range(), ""); 17 | static_assert(origin::Bidirectional_range(), ""); 18 | 19 | static_assert(not origin::Bidirectional_range(), ""); 20 | static_assert(not origin::Bidirectional_range(), ""); 21 | 22 | int main() { } 23 | -------------------------------------------------------------------------------- /origin/range/core.test/forward_range.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | 11 | using In = std::istream_iterator; 12 | using Fwd = std::forward_list; 13 | using List = std::list; 14 | using Vec = std::vector; 15 | 16 | static_assert(origin::Forward_range(), ""); 17 | static_assert(origin::Forward_range(), ""); 18 | static_assert(origin::Forward_range(), ""); 19 | static_assert(origin::Forward_range(), ""); 20 | static_assert(origin::Forward_range(), ""); 21 | static_assert(origin::Forward_range(), ""); 22 | 23 | int main() { } 24 | -------------------------------------------------------------------------------- /origin/range/core.test/input_range.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | using Fwd = std::forward_list; 11 | using List = std::list; 12 | using Vec = std::vector; 13 | 14 | static_assert(origin::Input_range(), ""); 15 | static_assert(origin::Input_range(), ""); 16 | static_assert(origin::Input_range(), ""); 17 | static_assert(origin::Input_range(), ""); 18 | static_assert(origin::Input_range(), ""); 19 | static_assert(origin::Input_range(), ""); 20 | 21 | int main() { } 22 | -------------------------------------------------------------------------------- /origin/range/core.test/iterator_type.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | 12 | // True when the range R has iterator type T. 13 | template 14 | constexpr bool Has_iterator_type() 15 | { 16 | return origin::Same, T>(); 17 | } 18 | 19 | using Fwd = std::forward_list; 20 | using List = std::list; 21 | using Vec = std::vector; 22 | 23 | static_assert(Has_iterator_type(), ""); 24 | static_assert(Has_iterator_type(), ""); 25 | static_assert(Has_iterator_type(), ""); 26 | static_assert(Has_iterator_type(), ""); 27 | static_assert(Has_iterator_type(), ""); 28 | static_assert(Has_iterator_type(), ""); 29 | static_assert(Has_iterator_type(), ""); 30 | static_assert(Has_iterator_type(), ""); 31 | 32 | int main() { } 33 | -------------------------------------------------------------------------------- /origin/range/core.test/output_range.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | 11 | using In = std::istream_iterator; 12 | using Fwd = std::forward_list; 13 | using List = std::list; 14 | using Vec = std::vector; 15 | 16 | static_assert(origin::Output_range(), ""); 17 | static_assert(origin::Output_range(), ""); 18 | static_assert(origin::Output_range(), ""); 19 | 20 | int main() { } 21 | -------------------------------------------------------------------------------- /origin/range/core.test/random_access_range.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | using Fwd = std::forward_list; 11 | using List = std::list; 12 | using Vec = std::vector; 13 | 14 | static_assert(origin::Random_access_range(), ""); 15 | static_assert(origin::Random_access_range(), ""); 16 | 17 | static_assert(not origin::Random_access_range(), ""); 18 | static_assert(not origin::Random_access_range(), ""); 19 | static_assert(not origin::Random_access_range(), ""); 20 | static_assert(not origin::Random_access_range(), ""); 21 | 22 | int main() { } 23 | -------------------------------------------------------------------------------- /origin/range/core.test/range.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | 11 | using Fwd = std::forward_list; 12 | using List = std::list; 13 | using Vec = std::vector; 14 | 15 | static_assert(origin::Range(), ""); 16 | static_assert(origin::Range(), ""); 17 | static_assert(origin::Range(), ""); 18 | static_assert(origin::Range(), ""); 19 | static_assert(origin::Range(), ""); 20 | 21 | static_assert(origin::Range(), ""); 22 | static_assert(origin::Range(), ""); 23 | 24 | template 25 | void f(R&& range) { } 26 | 27 | int main() { 28 | Vec v1; 29 | const Vec v2 { }; 30 | f(v1); 31 | f(v2); 32 | f(Vec{}); 33 | } 34 | 35 | -------------------------------------------------------------------------------- /origin/range/core.test/sentinel_type.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | 12 | // TODO: Construct some ranges whose iterator/sentinel types differ. 13 | 14 | // True when the range R has sentinel type T. 15 | template 16 | constexpr bool Has_sentinel_type() 17 | { 18 | return origin::Same, T>(); 19 | } 20 | 21 | using Fwd = std::forward_list; 22 | using List = std::list; 23 | using Vec = std::vector; 24 | 25 | static_assert(Has_sentinel_type(), ""); 26 | static_assert(Has_sentinel_type(), ""); 27 | static_assert(Has_sentinel_type(), ""); 28 | static_assert(Has_sentinel_type(), ""); 29 | static_assert(Has_sentinel_type(), ""); 30 | static_assert(Has_sentinel_type(), ""); 31 | static_assert(Has_sentinel_type(), ""); 32 | static_assert(Has_sentinel_type(), ""); 33 | 34 | int main() { } 35 | -------------------------------------------------------------------------------- /origin/range/core.test/size_type.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | 11 | // True when the range R has size type T. 12 | template 13 | constexpr bool Has_size_type() 14 | { 15 | return origin::Same, T>(); 16 | } 17 | 18 | using Fwd = std::forward_list; 19 | using List = std::list; 20 | using Vec = std::vector; 21 | 22 | static_assert(Has_size_type(), ""); 23 | static_assert(Has_size_type(), ""); 24 | static_assert(Has_size_type(), ""); 25 | static_assert(Has_size_type(), ""); 26 | 27 | int main() { } 28 | -------------------------------------------------------------------------------- /origin/range/core.test/test_resource.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #ifndef TEST_RESOURCE_HPP 5 | #define TEST_RESOURCE_HPP 6 | 7 | // A move-only type. 8 | struct res 9 | { 10 | res(res&&) = default; 11 | res& operator=(res&&) = default; 12 | 13 | res(const res&) = delete; 14 | res& operator=(const res&) = delete; 15 | }; 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /origin/range/core.test/value_type.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | 11 | // True when the range R has size type T. 12 | template 13 | constexpr bool Has_value_type() 14 | { 15 | return origin::Same, T>(); 16 | } 17 | 18 | using Fwd = std::forward_list; 19 | using List = std::list; 20 | using Vec = std::vector; 21 | 22 | static_assert(Has_value_type(), ""); 23 | static_assert(Has_value_type(), ""); 24 | static_assert(Has_value_type(), ""); 25 | static_assert(Has_value_type(), ""); 26 | 27 | int main() { } 28 | -------------------------------------------------------------------------------- /origin/range/range.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include "range.hpp" 5 | 6 | 7 | -------------------------------------------------------------------------------- /origin/range/range.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #ifndef ORIGIN_RANGE_RANGE_HPP 5 | #define ORIGIN_RANGE_RANGE_HPP 6 | 7 | #include 8 | 9 | 10 | namespace origin 11 | { 12 | 13 | 14 | // -------------------------------------------------------------------------- // 15 | // Begin and end [range.be] 16 | // 17 | // In many cases (i.e., constructors), we want to invoke begin and 18 | // end so that ADL finds appropriate overloads. However, that cannot 19 | // be done within a member-initializer-list, unless the enclosing 20 | // namespace brings the names std::begin and std::end into scope. 21 | // 22 | // The std_begin and std_end functions can be used as a workaround. 23 | 24 | template 25 | inline decltype(auto) 26 | std_begin(T&& t) 27 | { 28 | using std::begin; 29 | return begin(std::forward(t)); 30 | } 31 | 32 | 33 | template 34 | inline decltype(auto) 35 | std_end(T&& t) 36 | { 37 | using std::end; 38 | return end(std::forward(t)); 39 | } 40 | 41 | 42 | 43 | // -------------------------------------------------------------------------- // 44 | // Range size 45 | // 46 | // Returns the size of the range, the number of increments required 47 | // to move from the beginning to the end. 48 | 49 | template 50 | inline Size_type 51 | size(R&& range) 52 | { 53 | using std::begin; 54 | using std::end; 55 | return std::distance(begin(range), end(range)); 56 | } 57 | 58 | 59 | // -------------------------------------------------------------------------- // 60 | // Range base 61 | // 62 | // The range base class provides appropriate typedefs for the value and 63 | // size type for range adaptors. 64 | template 65 | struct range_base 66 | { 67 | using value_type = Value_type; 68 | using size_type = Make_unsigned>; 69 | }; 70 | 71 | 72 | 73 | // -------------------------------------------------------------------------- // 74 | // Bounded Range 75 | // 76 | // The bounded range class encapsulates an iterator range bounded 77 | // by a pair of iterators. 78 | template 79 | class bounded_range : public range_base 80 | { 81 | public: 82 | using iterator = I; 83 | 84 | // A default-constructed range is empty. 85 | bounded_range() 86 | : first(), last(first) 87 | { } 88 | 89 | // Initialize the range with a lower bound, f, and an upper 90 | // bound, l. 91 | bounded_range(I f, I l) 92 | : first(f), last(l) 93 | { } 94 | 95 | // Iterators 96 | iterator begin() const { return first; } 97 | iterator end() const { return last; } 98 | 99 | private: 100 | I first; 101 | I last; 102 | }; 103 | 104 | 105 | } // namespace origin 106 | 107 | 108 | #endif 109 | -------------------------------------------------------------------------------- /origin/range/range.test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2009-2015 Andrew Sutton 2 | # All rights reserved 3 | 4 | link_libraries(origin-range) 5 | 6 | add_run_test(range_size size.cpp) 7 | add_run_test(range_bounded bounded.cpp) 8 | -------------------------------------------------------------------------------- /origin/range/range.test/bounded.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | 10 | template 11 | constexpr bool Has_size_type() 12 | { 13 | return origin::Same, T>(); 14 | } 15 | 16 | 17 | template 18 | constexpr bool Has_value_type() 19 | { 20 | return origin::Same, T>(); 21 | } 22 | 23 | 24 | template 25 | constexpr bool Has_iterator_type() 26 | { 27 | return origin::Same, T>(); 28 | } 29 | 30 | 31 | static_assert(origin::Range>(), ""); 32 | static_assert(Has_size_type, std::size_t>(), ""); 33 | static_assert(Has_value_type, int>(), ""); 34 | static_assert(Has_iterator_type, int*>(), ""); 35 | 36 | 37 | template 38 | void test_default() 39 | { 40 | origin::bounded_range range; 41 | assert(origin::size(range) == 0); 42 | } 43 | 44 | 45 | template 46 | void test_init(I first, I last) 47 | { 48 | origin::bounded_range range(first, last); 49 | auto first2 = range.begin(); 50 | auto last2 = range.end(); 51 | while (first2 != last2) { 52 | assert(first2 == first); 53 | ++first2; 54 | ++first; 55 | } 56 | assert(last2 == last); 57 | } 58 | 59 | 60 | int main() 61 | { 62 | using Vec = std::vector; 63 | 64 | test_default(); 65 | test_default(); 66 | test_default(); 67 | 68 | int a[3] = {1, 2, 3}; 69 | test_init (a, a + 3); 70 | 71 | Vec v {1, 2, 3}; 72 | test_init(v.begin(), v.end()); 73 | } 74 | -------------------------------------------------------------------------------- /origin/range/range.test/size.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2015 Andrew Sutton 2 | // All rights reserved 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | 11 | template 12 | void test(R&& range, std::size_t n) 13 | { 14 | assert(origin::size(range) == n); 15 | } 16 | 17 | 18 | int main() 19 | { 20 | int a[3] = {1, 2, 3}; 21 | test(a, 3); 22 | 23 | std::list l; 24 | test(l, 0); 25 | 26 | std::vector v; 27 | test(v, 0); 28 | } 29 | --------------------------------------------------------------------------------