├── .clang-format
├── .github
├── ISSUE_TEMPLATE
│ ├── gcl-bug-report.md
│ └── gcl-feature-request.md
└── workflows
│ ├── MSBuild-Windows-CL_latest.yml
│ ├── cmake-Ubuntu-clang_latest.yml
│ ├── cmake-Ubuntu-gcc_10.yml
│ └── cmake-Windows-ClangCL_latest.yml
├── .gitignore
├── CMakeLists.txt
├── CMakeSettings.json
├── GCL_CPP.sln
├── GCL_CPP.vcxproj
├── GCL_CPP.vcxproj.filters
├── LICENSE
├── README.md
├── includes
├── gcl
│ ├── algorithms
│ │ ├── README.md
│ │ ├── algorithms.hpp
│ │ ├── maths.hpp
│ │ └── ranges.hpp
│ ├── compile_time_constant
│ │ ├── README.md
│ │ ├── algorithms.hpp
│ │ ├── algorithms
│ │ │ ├── array.hpp
│ │ │ └── tuple.hpp
│ │ └── ctc.hpp
│ ├── concepts.hpp
│ ├── container
│ │ ├── concepts.hpp
│ │ ├── interval_map.hpp
│ │ ├── tuple_view.hpp
│ │ └── utility.hpp
│ ├── cx
│ │ ├── array.hpp
│ │ ├── crc32_hash.hpp
│ │ ├── cx.hpp
│ │ ├── typeinfo.hpp
│ │ └── unordered_map.hpp
│ ├── functional.hpp
│ ├── io
│ │ ├── concepts.hpp
│ │ ├── io.hpp
│ │ ├── policy.hpp
│ │ ├── serialization.hpp
│ │ └── traits.hpp
│ ├── mp
│ │ ├── cast.hpp
│ │ ├── concepts.hpp
│ │ ├── function_traits.hpp
│ │ ├── meta
│ │ │ ├── functional.hpp
│ │ │ ├── meta.hpp
│ │ │ ├── operations.hpp
│ │ │ ├── pack_trait.hpp
│ │ │ └── tuple.hpp
│ │ ├── mp.hpp
│ │ ├── pack_traits.hpp
│ │ ├── preprocessor.hpp
│ │ ├── type_tag.hpp
│ │ ├── type_traits.hpp
│ │ ├── utility.hpp
│ │ └── value_traits.hpp
│ └── pattern
│ │ ├── ecs.hpp
│ │ └── strong_type.hpp
└── gcl_cpp_deprecated
│ ├── IO.h
│ ├── color.h
│ ├── container
│ ├── component_aggregator.hpp
│ ├── entity_vector.hpp
│ ├── linear_vector.hpp
│ ├── polymorphic_reference.hpp
│ ├── polymorphic_vector.hpp
│ └── utility.hpp
│ ├── event.hpp
│ ├── exception.hpp
│ ├── functional.hpp
│ ├── introspection.hpp
│ ├── maths.h
│ ├── mp.hpp
│ ├── old
│ ├── EventHandler.h
│ ├── Experimental.h
│ ├── Monitoring.h
│ ├── SelfUpdate.h
│ ├── TestUtils.h
│ ├── control_center.hpp
│ ├── filesystem.hpp
│ ├── log.hpp
│ ├── ownership.hpp
│ ├── task.hpp
│ └── thread.hpp
│ ├── pattern
│ ├── ecs.hpp
│ └── state_machine.hpp
│ ├── preprocessor.hpp
│ ├── serialisation.hpp
│ ├── signals.hpp
│ ├── test.hpp
│ ├── tuple_utils.hpp
│ ├── type_index.hpp
│ └── type_info.hpp
└── tests
├── CMakeLists.txt
├── Main.cpp
└── gcl
└── test
├── container.hpp
├── container
├── component_aggregator.hpp
├── entity_vector.hpp
├── polymorphic_reference.hpp
└── polymorphic_vector.hpp
├── event.hpp
├── gcl.hpp
├── introspection.hpp
├── mp.hpp
├── pattern.hpp
├── pattern
└── ecs.hpp
├── test.hpp
├── type_index.hpp
└── type_info.hpp
/.clang-format:
--------------------------------------------------------------------------------
1 | ---
2 | BasedOnStyle: Microsoft
3 | Language: Cpp
4 | AlignAfterOpenBracket: AlwaysBreak
5 | AlignConsecutiveDeclarations: 'true'
6 | AlignTrailingComments: 'true'
7 | # AllowShortEnumsOnASingleLine : 'true'
8 | AllowShortFunctionsOnASingleLine: InlineOnly
9 | # AllowShortLambdasOnASingleLine: SLS_Inline
10 | AlwaysBreakBeforeMultilineStrings: 'true'
11 | AlwaysBreakTemplateDeclarations: 'Yes'
12 | BinPackArguments: 'false'
13 | BinPackParameters: 'false'
14 | # BreakBeforeConceptDeclarations: 'true'
15 | # IndentRequires: 'true'
16 | SpaceAfterTemplateKeyword: 'true'
17 | SpacesInAngles: 'false'
18 | # BreakBeforeBraces: Allman
19 | BreakBeforeBraces: Custom
20 | BraceWrapping:
21 | AfterEnum: true
22 | AfterClass: false
23 | AfterStruct: false
24 | #BeforeLambdaBody: false
25 | SplitEmptyFunction: false
26 | SplitEmptyRecord: false
27 |
28 | BreakBeforeTernaryOperators: 'true'
29 | BreakConstructorInitializers: BeforeComma
30 | BreakInheritanceList: BeforeComma
31 | Cpp11BracedListStyle: 'true'
32 | NamespaceIndentation: All
33 | FixNamespaceComments: 'false'
34 | PointerAlignment: "Left"
35 | IndentWidth: 4
36 | TabWidth: 4
37 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/gcl-bug-report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: GCL Bug report
3 | about: Create a report to help us improve GCL components
4 | title: "[BUG]"
5 | labels: bug
6 | assignees: ''
7 |
8 | ---
9 |
10 | ### **Component name**
11 |
12 | *(ex : `gcl::mp::function_traits`. use `gcl` if your issue impacts the whole library)*
13 |
14 | ### **Context**
15 |
16 | - OS : *(ex : Ubuntu 20.04)*
17 | - Configuration(s) : *(ex : x64-RelWithDebInfos)*
18 | - Compiler(s) name + release : *(ex : `Clang 11.0.1`)*
19 | - Runtime or compile-time issue ?
20 | - [ ] Compile time issue
21 | - [ ] Runtime issue
22 | - Project build / generation
23 | - [ ] CMake
24 | - [ ] MSVC
25 | - [ ] Direct include `gcl/includes` *(git submodule, CMake FetchContent/ExternalProject_Add, etc.)*
26 |
27 | ### **Describe the bug**
28 | A clear and concise description of what the bug is.
29 |
30 | ### **To Reproduce**
31 | A minimal code example that demonstrates the issue. `Godbolt` links are OK too.
32 |
33 | ### **Expected behavior**
34 | A clear and concise description of what you expected to happen.
35 |
36 | ### **Additional context**
37 | Add any other context about the problem here.
38 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/gcl-feature-request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: GCL enhancement / feature request
3 | about: Suggest enhancement or new feature your idea about GCL
4 | title: "[REQUEST]"
5 | labels: enhancement
6 | assignees: ''
7 |
8 | ---
9 |
10 | ### **Scope**
11 |
12 | - [ ] C++
13 | - [ ] New `gcl` component
14 | - [ ] New language standard support
15 | - [ ] CMake
16 | - [ ] CI
17 | - [ ] Configuration support
18 | - [ ] Compiler support
19 | - [ ] OS support
20 | - [ ] Architecture support
21 | - [ ] Documentation
22 |
23 | ### **Description**
24 |
25 | A clear and concise description of what the suggestion is about.
26 |
27 | *Examples :*
28 |
29 | - `C++` : new `gcl::event` implementation
30 | - `configuration`: Add Windows-MsCL-x64-RelWithDebInfos configuration support)*
31 |
32 | ### **Details**
33 |
34 | Details about your suggestion.
35 | Might contain implementation details, designs, links to external components, etc.
36 |
37 | ### **[optional] Expected behavior**
38 | A clear and concise description of what you expected to happen.
39 |
40 | ### **[optional] Additional context**
41 | Add any other context about the suggestion here here.
42 |
--------------------------------------------------------------------------------
/.github/workflows/MSBuild-Windows-CL_latest.yml:
--------------------------------------------------------------------------------
1 | name: MSBuild-Windows-CL_latest
2 |
3 | on: [push, pull_request]
4 |
5 | env:
6 | SOLUTION_FILE_PATH: .
7 |
8 | jobs:
9 | build:
10 | runs-on: windows-latest
11 |
12 | strategy:
13 | matrix:
14 | BUILD_TYPE: [Debug, Release]
15 |
16 | steps:
17 | - uses: actions/checkout@v2
18 |
19 | - name: Add MSBuild to PATH
20 | uses: microsoft/setup-msbuild@v1
21 |
22 | - name: Restore NuGet packages
23 | working-directory: ${{env.GITHUB_WORKSPACE}}
24 | run: nuget restore ${{env.SOLUTION_FILE_PATH}}
25 |
26 | - name: Build - ${{matrix.BUILD_TYPE}}
27 | working-directory: ${{env.GITHUB_WORKSPACE}}
28 | # Add additional options to the MSBuild command line here (like platform or verbosity level).
29 | # See https://docs.microsoft.com/visualstudio/msbuild/msbuild-command-line-reference
30 | run: msbuild /m /p:Configuration=${{matrix.BUILD_TYPE}} ${{env.SOLUTION_FILE_PATH}}
31 |
--------------------------------------------------------------------------------
/.github/workflows/cmake-Ubuntu-clang_latest.yml:
--------------------------------------------------------------------------------
1 | name: cmake-Ubuntu-clang_latest
2 |
3 | on: [push, pull_request]
4 |
5 | jobs:
6 | build:
7 |
8 | runs-on: ubuntu-latest
9 |
10 | strategy:
11 | matrix:
12 | BUILD_TYPE: [Debug, Release]
13 | STL_IMPLEMENTATION: [libstdc++, libc++ -lc++abi]
14 |
15 | steps:
16 | - uses: actions/checkout@v2
17 |
18 | - name: Initialize compiler (Clang, latest)
19 | run: |
20 | sudo apt update
21 | sudo apt install libstdc++-10-dev
22 | sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)"
23 | sudo update-alternatives \
24 | --install /usr/bin/clang clang /usr/bin/clang-12 100
25 | sudo update-alternatives \
26 | --install /usr/bin/clang++ clang++ /usr/bin/clang++-12 100
27 | sudo apt install libc++1-12 libc++-12-dev libc++abi-12-dev libc++abi1-12
28 |
29 | - name: cmake create build env - ${{matrix.BUILD_TYPE}} - ${{matrix.STL_IMPLEMENTATION}}
30 | run: |
31 | cmake -E make_directory ${{github.workspace}}/out/build/${{matrix.BUILD_TYPE}}
32 | cmake -E make_directory ${{github.workspace}}/out/install/${{matrix.BUILD_TYPE}}
33 |
34 | - name: cmake cache - ${{matrix.BUILD_TYPE}} - ${{matrix.STL_IMPLEMENTATION}}
35 | run: |
36 | cmake \
37 | -DCMAKE_CXX_FLAGS="-stdlib=${{matrix.STL_IMPLEMENTATION}}" \
38 | -DGCL_BUILD_TEST:BOOL=TRUE \
39 | -DCMAKE_BUILD_TYPE:STRING="${{matrix.BUILD_TYPE}}" \
40 | -DCMAKE_INSTALL_PREFIX:PATH=${{github.workspace}}/out/install/${{matrix.BUILD_TYPE}} \
41 | -S ${{github.workspace}} \
42 | -B ${{github.workspace}}/out/build/${{matrix.BUILD_TYPE}}
43 |
44 | env:
45 | CC: clang-12
46 | CXX: clang++-12
47 |
48 | - name: cmake build - ${{matrix.BUILD_TYPE}} - ${{matrix.STL_IMPLEMENTATION}}
49 | run: |
50 | cmake \
51 | --build ${{github.workspace}}/out/build/${{matrix.BUILD_TYPE}} \
52 | --config ${{matrix.BUILD_TYPE}}
53 |
54 | #- name: Test
55 | # working-directory: ${{github.workspace}}/build
56 | # shell: bash
57 | # # Execute tests defined by the CMake configuration.
58 | # # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
59 | # run: ctest -C $BUILD_TYPE
60 |
--------------------------------------------------------------------------------
/.github/workflows/cmake-Ubuntu-gcc_10.yml:
--------------------------------------------------------------------------------
1 | name: cmake-Ubuntu-gcc_10
2 |
3 | on: [push, pull_request]
4 |
5 | jobs:
6 | build:
7 |
8 | runs-on: ubuntu-latest
9 |
10 | strategy:
11 | matrix:
12 | BUILD_TYPE: [Debug, Release]
13 |
14 | steps:
15 | - uses: actions/checkout@v2
16 |
17 | - name: Initialize compiler (GCC)
18 | run: |
19 | sudo apt update
20 | sudo apt install gcc-10 g++-10
21 | sudo update-alternatives \
22 | --install /usr/bin/gcc gcc /usr/bin/gcc-10 100 \
23 | --slave /usr/bin/g++ g++ /usr/bin/g++-10 \
24 | --slave /usr/bin/gcov gcov /usr/bin/gcov-10
25 |
26 | - name: cmake create build env - ${{matrix.BUILD_TYPE}}
27 | run: |
28 | cmake -E make_directory ${{github.workspace}}/out/build/${{matrix.BUILD_TYPE}}
29 | cmake -E make_directory ${{github.workspace}}/out/install/${{matrix.BUILD_TYPE}}
30 |
31 | - name: cmake cache - ${{matrix.BUILD_TYPE}}
32 | #shell: bash
33 | #working-directory: ${{github.workspace}}/out/build/${{matrix.BUILD_TYPE}}
34 | run: |
35 | cmake \
36 | -DGCL_BUILD_TEST:BOOL=TRUE \
37 | -DCMAKE_BUILD_TYPE:STRING=${{matrix.BUILD_TYPE}} \
38 | -DCMAKE_INSTALL_PREFIX:PATH=${{github.workspace}}/out/install/${{matrix.BUILD_TYPE}} \
39 | -S ${{github.workspace}} \
40 | -B ${{github.workspace}}/out/build/${{matrix.BUILD_TYPE}}
41 |
42 | env:
43 | CC: gcc-10
44 | CXX: g++-10
45 |
46 | - name: cmake build - ${{matrix.BUILD_TYPE}}
47 | #working-directory: ${{github.workspace}}/out/build/${{matrix.BUILD_TYPE}}
48 | run: |
49 | cmake \
50 | --build ${{github.workspace}}/out/build/${{matrix.BUILD_TYPE}} \
51 | --config ${{matrix.BUILD_TYPE}}
52 |
53 | #- name: Test
54 | # working-directory: ${{github.workspace}}/build
55 | # shell: bash
56 | # # Execute tests defined by the CMake configuration.
57 | # # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
58 | # run: ctest -C $BUILD_TYPE
59 |
--------------------------------------------------------------------------------
/.github/workflows/cmake-Windows-ClangCL_latest.yml:
--------------------------------------------------------------------------------
1 | name: cmake-Windows-ClangCL
2 |
3 | on: [push, pull_request]
4 |
5 | env:
6 | SOLUTION_FILE_PATH: .
7 |
8 | jobs:
9 | build:
10 |
11 | runs-on: windows-latest
12 |
13 | strategy:
14 | matrix:
15 | BUILD_TYPE: [Debug, Release]
16 | ARCH: [Win32, x64]
17 | GENERATOR: ["Visual Studio 16 2019"]
18 |
19 | steps:
20 | - uses: actions/checkout@v2
21 |
22 | - name: cmake create build env - ${{matrix.ARCH}} ${{matrix.BUILD_TYPE}}
23 | run: |
24 | cmake -E make_directory ${{github.workspace}}/out/build/${{matrix.ARCH}}/${{matrix.BUILD_TYPE}}
25 | cmake -E make_directory ${{github.workspace}}/out/install/${{matrix.ARCH}}/${{matrix.BUILD_TYPE}}
26 |
27 | - name: cmake cache - ${{matrix.ARCH}} ${{matrix.BUILD_TYPE}}
28 | #working-directory: ${{github.workspace}}/out/build/${{matrix.ARCH}}/${{matrix.BUILD_TYPE}}
29 | run: |
30 | cmake `
31 | -DGCL_BUILD_TEST:BOOL=TRUE `
32 | -DCMAKE_BUILD_TYPE:STRING="${{matrix.BUILD_TYPE}}" `
33 | -DCMAKE_INSTALL_PREFIX:PATH=${{github.workspace}}/out/install/${{matrix.ARCH}}/${{matrix.BUILD_TYPE}} `
34 | -S ${{github.workspace}} `
35 | -B ${{github.workspace}}/out/build/${{matrix.ARCH}}/${{matrix.BUILD_TYPE}} `
36 | -G "${{matrix.GENERATOR}}" `
37 | -A ${{matrix.ARCH}} `
38 | -T ClangCL
39 |
40 | - name: cmake build - ${{matrix.ARCH}} ${{matrix.BUILD_TYPE}}
41 | #working-directory: ${{github.workspace}}/out/build/${{matrix.ARCH}}/${{matrix.BUILD_TYPE}}
42 | run: |
43 | cmake `
44 | --build ${{github.workspace}}/out/build/${{matrix.ARCH}}/${{matrix.BUILD_TYPE}} `
45 | --config ${{matrix.BUILD_TYPE}} `
46 | --parallel 10
47 |
48 | #- name: test
49 | # run: cd build ; ctest -j 10 -C Debug --output-on-failure
50 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # MSVC
2 | *.vs
3 | bin
4 | out
5 | Debug/
6 | Release/
7 | *.vcxproj.user
8 | *.idb
9 | *.pdb
10 |
11 | # CMake
12 | build/
13 |
14 | # Outputs
15 | *.o
16 | *.obj
17 | *.elf
18 | *.lo
19 | *.slo
20 | *.gch
21 | *.pch
22 | *.so
23 | *.so.*
24 | *.dylib
25 | *.dll
26 | *.lai
27 | *.la
28 | *.a
29 | *.lib
30 |
31 | x64
32 | x86
33 | *.exe
34 | *.out
35 | *.app
36 | *.i*86
37 | *.x86_64
38 | *.hex
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.8)
2 | project(GCL VERSION 2.0 LANGUAGES CXX)
3 |
4 | option(${PROJECT_NAME}_ENABLE_COMPILE_TIME_TESTS "${PROJECT_NAME} : Build compile-time tests ?" OFF)
5 | message(STATUS "${PROJECT_NAME} -- ${PROJECT_NAME}_ENABLE_COMPILE_TIME_TESTS is ${${PROJECT_NAME}_ENABLE_COMPILE_TIME_TESTS}")
6 | if (${${PROJECT_NAME}_ENABLE_COMPILE_TIME_TESTS})
7 | add_compile_definitions(${PROJECT_NAME}_ENABLE_COMPILE_TIME_TESTS)
8 | endif()
9 |
10 | add_library(gcl_cpp INTERFACE)
11 | target_include_directories(gcl_cpp INTERFACE
12 | ${CMAKE_CURRENT_SOURCE_DIR}/includes
13 | )
14 | target_compile_features(gcl_cpp INTERFACE
15 | cxx_std_20
16 | # C++11
17 | cxx_lambdas
18 | cxx_noexcept
19 | cxx_auto_type
20 | cxx_constexpr
21 | cxx_static_assert
22 | cxx_alias_templates
23 | cxx_rvalue_references
24 | # C++14
25 | cxx_decltype_auto
26 | cxx_generic_lambdas
27 | cxx_variable_templates
28 | cxx_variadic_templates
29 | cxx_return_type_deduction
30 | cxx_aggregate_default_initializers
31 | )
32 |
33 | option(${PROJECT_NAME}_BUILD_TEST "${PROJECT_NAME} : Build tests ?" OFF)
34 | message(STATUS "${PROJECT_NAME} -- ${PROJECT_NAME}_BUILD_TEST is ${${PROJECT_NAME}_BUILD_TEST}")
35 | if (${PROJECT_NAME}_BUILD_TEST)
36 | message(STATUS "${PROJECT_NAME} -- ${PROJECT_NAME}_BUILD_TEST -- forcing ${PROJECT_NAME}_ENABLE_COMPILE_TIME_TESTS to ON")
37 | add_compile_definitions(${PROJECT_NAME}_ENABLE_COMPILE_TIME_TESTS)
38 | message(STATUS "${PROJECT_NAME} -- ${PROJECT_NAME}_BUILD_TEST -- forcing ${PROJECT_NAME}_ENABLE_RUNTIME_TESTS to ON")
39 | add_compile_definitions(${PROJECT_NAME}_ENABLE_RUNTIME_TESTS)
40 | add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/tests)
41 | endif()
42 |
43 | # todo : include2dot
44 | # todo : dependency graph
45 | # cmake SRC_DIR --graphviz=xxx.dot
46 | # dot -Tpng xxx.dot xxx.pgf
47 |
--------------------------------------------------------------------------------
/GCL_CPP.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.30804.86
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GCL_CPP", "GCL_CPP.vcxproj", "{7D0A45A0-457D-4DDC-85BB-1ADC4522A653}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|x64 = Debug|x64
11 | Debug|x86 = Debug|x86
12 | Release|x64 = Release|x64
13 | Release|x86 = Release|x86
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {7D0A45A0-457D-4DDC-85BB-1ADC4522A653}.Debug|x64.ActiveCfg = Debug|x64
17 | {7D0A45A0-457D-4DDC-85BB-1ADC4522A653}.Debug|x64.Build.0 = Debug|x64
18 | {7D0A45A0-457D-4DDC-85BB-1ADC4522A653}.Debug|x86.ActiveCfg = Debug|Win32
19 | {7D0A45A0-457D-4DDC-85BB-1ADC4522A653}.Debug|x86.Build.0 = Debug|Win32
20 | {7D0A45A0-457D-4DDC-85BB-1ADC4522A653}.Release|x64.ActiveCfg = Release|x64
21 | {7D0A45A0-457D-4DDC-85BB-1ADC4522A653}.Release|x64.Build.0 = Release|x64
22 | {7D0A45A0-457D-4DDC-85BB-1ADC4522A653}.Release|x86.ActiveCfg = Release|Win32
23 | {7D0A45A0-457D-4DDC-85BB-1ADC4522A653}.Release|x86.Build.0 = Release|Win32
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(ExtensibilityGlobals) = postSolution
29 | SolutionGuid = {936D6F6A-8EC1-4CF0-A70E-28F052AECBA4}
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # **GCL C++**
2 |
3 | [](https://github.com/GuillaumeDua/GCL_CPP/actions/workflows/cmake-Ubuntu-clang_latest.yml)
4 | [](https://github.com/GuillaumeDua/GCL_CPP/actions/workflows/cmake-Ubuntu-gcc_10.yml)
5 | [](https://github.com/GuillaumeDua/GCL_CPP/actions/workflows/MSBuild-Windows-CL_latest.yml)
6 | [](https://github.com/GuillaumeDua/GCL_CPP/actions/workflows/cmake-Windows-ClangCL.yml)
7 |
8 | :construction: **WIP** : [see milestone v1 -> v2](https://github.com/GuillaumeDua/GCL_CPP/milestone/2)
9 |
10 | ---
11 |
12 | This **modern-C++**, **header-only library** is a stack of useful and convinient components that make my everyday projects & jobs way easier.
13 |
14 | Each **component** *(spli by namespaces)* aims to be :
15 |
16 | - **easy-to-use**
17 | - **easy-to-maintain**
18 | - **powerful**
19 |
20 | > **NB :** This library is a never-ending WIP, as it matches needs according to the C++ standards and compilers implementations.
21 | > Thus, many components only exists to fill what I consider to be STL holes, and so are likely to disappear when standard features are implemented *-and released-* in the standard and by compilers.
22 |
23 | ## Build
24 |
25 | This library is header-only, meaning you only need to add `includes/gcl` to your include path.
26 |
27 | However, a `CMake` target exposes an `gcl_cpp` INTERFACE library target that you can integrate into your build.
28 |
29 | Currently, the only available option is `gcl_cpp_BUILD_TEST` - which is set to `OFF` by default - that generates a binary to run runtime tests.
30 |
31 | ## Tests
32 |
33 | As this library components are mainly template-metaprogramming or constexpr ones, most of the tests are processed at **`compile-time`**.
34 |
35 | Currently, there is no option to disable compile-time tests.
36 | *If you need such option, create a Github issue, or make a pull-request.*
37 |
38 | As mentioned in the previous section, a CMake target can be generate, when enabling the `gcl_cpp_BUILD_TEST` option.
39 | However, it only cover runtime tests.
40 |
41 | ## Versions
42 |
43 | | Name | Description |
44 | | ---- | ----------- |
45 | | **`v2`** | [WIP/refactoring](https://github.com/GuillaumeDua/GCL_CPP/milestone/2) to only use C++17/2a/20 implementations |
46 | | **`v1`** | **Legacy** tag that still exists for projects that depends on, but is no longer maintained
Offers C++11/14/17 implementations in `gcl` namespace
as well as C++98/03 implementations in `gcl::deprecated` namespace |
47 |
48 | ## Features
49 |
50 | ### table-of-content
51 |
52 | | **component** name | description |
53 | |--------------------|--------------------------------------------------------------------------------------------|
54 | | `mp` | meta-programming elements to provide computation at compile-time |
55 | | `cx` | constexpr elements |
56 | | `ctc` | compile-time constants.
mainly provides algorithms to manipulate `std::array` and `std::tuple` at compile-time |
57 | | `io` | io manipulation, mainly for serialization |
58 | | `container` | containers |
59 | | `pattern` | mid-level design patterns, such as ECS |
60 | | [algorithms](./includes/gcl/algorithms/README.md) | some algorithms |
61 | | `functional` | function-related elements |
62 | | `concepts` | concepts definition. Note that most concepts are defined within components they are related to.
For instance, `gcl::mp::concepts` and `gcl::io::concepts` |
63 |
64 |
65 | ## Compilers support
66 |
67 | This library aims to compile using the following compilers :
68 |
69 | - `GCC`
70 | - `Clang`
71 | - `MsVC-CL`
72 | - `MS Clang-CL`
73 |
74 | *If at some point, a compiler does not support a specific feature, this information will be register as a limitation in-code comment
75 | Also, a warning will be generated at compile-time accordingly.*
76 |
77 | > - Example : `Clang 11.0.0` does not implement `"Lambdas in unevaluated contexts" (P0315R4)`
78 |
79 | ### Currently known limitations
80 |
81 | #### **`Clang`** / **`Clang-CL`**
82 |
83 | | File | Element | Description |
84 | | --------- | ------- | ----------- |
85 | | gcl/mp/pack_traits.hpp | `gcl::mp::type_traits::index_of` | uses an alternative implementation that use recursion, in opposition to other compilers |
86 | | gcl/mp/pack_traits.hpp | `gcl::mp::pack_traits<...>::index_of_v`
`gcl::mp::pack_traits<...>::first_index_of_v`
`gcl::mp::pack_traits<...>::last_index_of_v` | Known limitation of Clang 12.0.0
*Invalid operands to binary expression ('const auto' and 'int')* |
87 |
88 | #### **`Clang-CL`**
89 |
90 | | File | Element | Description |
91 | | --------- | ------- | ----------- |
92 | | gcl/cx/array.hpp | `gcl::cx::array::remove_duplicates_v` | a non-type template parameter cannot have type 'std::array' |
93 |
94 | #### **`GCC`**
95 |
96 | None.
97 |
98 | #### **`MsVC-CL`**
99 |
100 | None.
101 |
102 | ## STL implementations support
103 |
104 | ### **`libstdc++`**
105 |
106 | None.
107 |
108 | ### **`libc++`**
109 |
110 | Broken on release prior to 13 (requires concepts implementations)
111 |
112 | ### About the name
113 |
114 | > `GCL` stands for `Guss's Common Library`
115 |
--------------------------------------------------------------------------------
/includes/gcl/algorithms/README.md:
--------------------------------------------------------------------------------
1 | # **GCL C++** : Algorithms
2 |
3 | This component provide - *constexpr* - algorithms used in the `gcl` library implementation.
4 |
5 | ## Details
6 |
7 | | | |
8 | | - | - |
9 | | namespace | `gcl::algorithms` |
10 | | path | `includes/gcl/algorithms` |
11 |
12 | Grouped in : `gcl/algorithms/algorithms.hpp`
13 |
14 | ### **`gcl::algorithms::maths`**
15 |
16 | Grouped in : `gcl/algorithms/algorithms/maths.hpp`
17 |
18 | | Element name | Description | example |
19 | | ------------ | ----------- | ------- |
20 | | maths::distance(T, T) | return the distance between two values | `distance(1, -1) == 2` |
21 | | maths::abs(T) | absolute value with boundary safety
| `abs(-1) == 1` |
22 |
23 | ### **`gcl::algorithms::ranges`**
24 |
25 | Grouped in : `gcl/algorithms/algorithms/ranges.hpp`
26 |
27 | | Element name | Description | example |
28 | | ------------ | ----------- | ------- |
29 | | ranges::is_in_range(Range, input) | return true if `intput` is in `range` | `is_in_range({1,2,3}, 2) == true` |
30 | | ranges::is_in_range(RangeIt, RangeIt, InputIt) | same as above, but using `begin`, `end` iterators | |
31 |
--------------------------------------------------------------------------------
/includes/gcl/algorithms/algorithms.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 |
6 | #include
7 | #include
8 | #include
9 | #include
10 |
11 | namespace gcl::algorithms
12 | {
13 | // todo :
14 | // for_each that detected if the projection takes an iterator or value as parameter ?
15 |
16 | // Similar to `std::for_each` by defaut
17 | // but add the ability to project iterator (not values)
18 | // for values, simply use common projections
19 | template
20 | // requires
21 | // std::invocable and
22 | // std::invocable>>
23 |
24 | constexpr UnaryFunction for_each_it(
25 | iterator_type range_begin, iterator_type range_end, UnaryFunction f, Projection proj = {})
26 | // noexcept(...)
27 | {
28 | static_assert(std::is_invocable_v);
29 | using projection_result_t = std::invoke_result_t;
30 | static_assert(std::is_invocable_v>);
31 |
32 | for (; range_begin != range_end; ++range_begin)
33 | {
34 | auto value = std::invoke(proj, range_begin);
35 | std::invoke(f, std::move(value));
36 | }
37 | return f;
38 | }
39 |
40 | template
41 | [[nodiscard]] constexpr auto adjacent(container_type& container, iterator_type it) noexcept
42 | -> std::pair
43 | {
44 | if (it == std::cend(container))
45 | return std::pair{it, it};
46 | return std::pair{
47 | it == std::begin(container) ? std::end(container) : std::prev(it),
48 | it == std::end(container) ? it : std::next(it)};
49 | }
50 | template
51 | [[nodiscard]] constexpr auto adjacent_if(container_type & container, iterator_type it, Predicate predicate)
52 | noexcept(std::is_nothrow_invocable_v)
53 | -> decltype(adjacent(container, it)) {
54 |
55 | auto adjacent_result = adjacent(container, it);
56 | auto transformation = [&](auto & value){
57 | if (value not_eq std::end(container) and not predicate(*value))
58 | value = std::end(container);
59 | };
60 |
61 | [&](std::index_sequence){
62 | static_assert((std::is_invocable_v(adjacent_result))> && ...));
63 | ((transformation(std::get(adjacent_result))), ...);
64 | }(std::make_index_sequence>{});
65 | return adjacent_result;
66 | }
67 | }
68 |
69 | #ifdef GCL_ENABLE_COMPILE_TIME_TESTS
70 | #include
71 | namespace gcl::algorithms::tests
72 | {
73 | consteval void for_each_(){
74 |
75 | constexpr auto values = std::array{'a', 'b', 'c', 'd'};
76 | // same as std::for_each
77 | gcl::algorithms::for_each_it(
78 | std::cbegin(values), std::cend(values), [](const auto& value) { });
79 | // same as std::for_each with projection on it
80 | gcl::algorithms::for_each_it(
81 | std::cbegin(values),
82 | std::cend(values),
83 | [](const auto& projected_element) { const auto& [index, value] = projected_element; },
84 | [range_begin = std::cbegin(values)](const auto& it) {
85 | return std::pair{std::distance(range_begin, it), *it};
86 | });
87 | }
88 | consteval void adjacent_() {
89 | using namespace gcl::algorithms;
90 | { // adjacent(container, const_iterator)
91 | constexpr auto datas = std::array{1,2,3,4};
92 | static_assert(
93 | adjacent(datas, std::cbegin(datas)) ==
94 | std::pair{ std::cend(datas), std::next(std::cbegin(datas)) }
95 | );
96 | static_assert(
97 | adjacent(datas, std::next(std::cbegin(datas))) ==
98 | std::pair{ std::cbegin(datas), std::next(std::cbegin(datas), 2) }
99 | );
100 | }
101 | { // adjacent(container, iterator)
102 | }
103 | { // adajacent_if(container, const_iterator, Predicate)
104 |
105 | }
106 | { // adajacent_if(container, iterator, Predicate)
107 |
108 | }
109 | }
110 | }
111 | #endif
--------------------------------------------------------------------------------
/includes/gcl/algorithms/maths.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 |
7 | namespace gcl::algorithms::maths
8 | {
9 | template
10 | constexpr auto distance(T x, T y)
11 | {
12 | using value_type = std::conditional_t, std::intmax_t, std::uintmax_t>;
13 | return y >= x ? (value_type{y} - value_type{x}) : (value_type{x} - value_type{y});
14 | }
15 |
16 | // std::abs is not constexpr yet
17 | template
18 | requires(
19 | (std::is_signed_v and std::numeric_limits::min() >= std::numeric_limits::min() and
20 | std::numeric_limits::max() <= std::numeric_limits::max()) or
21 | not std::is_signed_v) constexpr inline auto abs(T arg) noexcept
22 | {
23 | if constexpr (std::is_signed_v)
24 | {
25 | std::intmax_t value{arg};
26 | return value < 0 ? -value : value;
27 | }
28 | else
29 | {
30 | return arg;
31 | }
32 | }
33 | }
34 |
35 | #if defined(GCL_ENABLE_COMPILE_TIME_TESTS)
36 | namespace gcl::algorithms::tests::maths
37 | {
38 | static_assert(gcl::algorithms::maths::distance(0, 0) == 0);
39 | static_assert(gcl::algorithms::maths::distance(-1, 1) == 2);
40 | static_assert(gcl::algorithms::maths::distance(1, -1) == 2);
41 | constexpr unsigned char uchar_zero{0};
42 | static_assert(
43 | gcl::algorithms::maths::distance(uchar_zero, std::numeric_limits::max()) ==
44 | std::numeric_limits::max());
45 |
46 | static_assert(gcl::algorithms::maths::abs(-1) == 1);
47 | static_assert(gcl::algorithms::maths::abs(1) == 1);
48 | }
49 | #endif
--------------------------------------------------------------------------------
/includes/gcl/algorithms/ranges.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 |
11 | namespace gcl::algorithms::ranges
12 | {
13 | template
14 | requires
15 | requires { typename std::common_type_t; }
16 | auto merge_uniques(const Ts & ... names) {
17 | using value_type = typename std::common_type_t;
18 | auto value = std::unordered_set{};
19 | (value.insert(std::cbegin(names), std::cend(names)), ...);
20 | return std::vector {
21 | std::move_iterator{std::begin(value)},
22 | std::move_iterator{std::end(value)}
23 | };
24 | }
25 |
26 | template
27 | constexpr bool is_in_range(RangeIterator range_begin, RangeIterator range_end, InputIterator input)
28 | {
29 | using range_category = typename std::iterator_traits::iterator_category;
30 | static_assert(std::is_base_of_v);
31 | using input_category = typename std::iterator_traits::iterator_category;
32 | static_assert(std::is_base_of_v);
33 |
34 | if constexpr (
35 | std::is_base_of_v and
36 | std::is_base_of_v)
37 | {
38 | if (range_begin > range_end)
39 | throw std::out_of_range{"gcl::algorithms::ranges::is_in_range"};
40 | return input >= range_begin and input <= range_end;
41 | }
42 | else
43 | { // UB if range_begin > range_end
44 | static_assert(std::equality_comparable_with);
45 | while (range_begin != range_end)
46 | {
47 | if (input == range_begin)
48 | return true;
49 | ++range_begin;
50 | }
51 | return false;
52 | }
53 | }
54 | template
55 | constexpr bool is_in_range(const Range & range_value, InputIterator input)
56 | {
57 | return is_in_range(std::begin(range_value), std::end(range_value), input);
58 | }
59 | }
60 |
61 | #if defined(GCL_ENABLE_RUNTIME_TESTS)
62 | #include