From 13225bfd8932a932cb15703cf8cfd393731c34c0 Mon Sep 17 00:00:00 2001 From: jkalias Date: Sun, 3 Jul 2022 23:03:39 +0200 Subject: [PATCH 01/44] removed explicit generator for Windows environment --- .github/workflows/cmake.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index 35786ad..56cb944 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -26,8 +26,7 @@ jobs: build_type: "Debug", cc: "cl", cxx: "cl", - environment_script: "C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Auxiliary/Build/vcvars64.bat", - generators: "Visual Studio 16 2019" + environment_script: "C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Auxiliary/Build/vcvars64.bat" } - { name: "Windows Latest MSVC (C++17)", @@ -35,8 +34,7 @@ jobs: build_type: "Debug", cc: "cl", cxx: "cl", - environment_script: "C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Auxiliary/Build/vcvars64.bat", - generators: "Visual Studio 16 2019" + environment_script: "C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Auxiliary/Build/vcvars64.bat" } - { name: "Ubuntu Latest GCC (C++11)", From c1b2a67c8110d45bb180d75a6650fac53196652f Mon Sep 17 00:00:00 2001 From: jkalias Date: Sun, 3 Jul 2022 23:25:48 +0200 Subject: [PATCH 02/44] generator VS 2022 --- .github/workflows/cmake.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index 56cb944..3f4d35c 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -26,7 +26,8 @@ jobs: build_type: "Debug", cc: "cl", cxx: "cl", - environment_script: "C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Auxiliary/Build/vcvars64.bat" + environment_script: "C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Auxiliary/Build/vcvars64.bat", + generators: "Visual Studio 17 2022" } - { name: "Windows Latest MSVC (C++17)", @@ -34,7 +35,8 @@ jobs: build_type: "Debug", cc: "cl", cxx: "cl", - environment_script: "C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Auxiliary/Build/vcvars64.bat" + environment_script: "C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Auxiliary/Build/vcvars64.bat", + generators: "Visual Studio 17 2022" } - { name: "Ubuntu Latest GCC (C++11)", From 642ed7fa13e86114367a2299f26ea8de70697b40 Mon Sep 17 00:00:00 2001 From: jkaliak Date: Mon, 4 Jul 2022 07:23:38 +0200 Subject: [PATCH 03/44] first commit of set --- include/export_def.h | 8 +- include/functional_set.h | 131 ++++++++++++++++++++++++++++++++ include/functional_vector.h | 1 + include/index_range.h | 2 +- src/CMakeLists.txt | 4 +- tests/CMakeLists.txt | 2 +- tests/functional_set_test.cc | 50 ++++++++++++ tests/functional_vector_test.cc | 43 +---------- tests/test_types.h | 55 ++++++++++++++ tests/warnings.h | 30 ++++++++ 10 files changed, 278 insertions(+), 48 deletions(-) create mode 100644 include/functional_set.h create mode 100644 tests/functional_set_test.cc create mode 100644 tests/test_types.h create mode 100644 tests/warnings.h diff --git a/include/export_def.h b/include/export_def.h index 1959f51..f8b9b0c 100644 --- a/include/export_def.h +++ b/include/export_def.h @@ -23,13 +23,13 @@ #pragma once #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) - #ifdef FUNCTIONAL_VECTOR_EXPORTS - #define FunctionalVectorExport __declspec( dllexport ) + #ifdef FUNCTIONAL_CPP_EXPORTS + #define FunctionalCppExport __declspec( dllexport ) #else - #define FunctionalVectorExport __declspec( dllimport ) + #define FunctionalCppExport __declspec( dllimport ) #endif #else - #define FunctionalVectorExport __attribute__ ((__visibility__("default"))) + #define FunctionalCppExport __attribute__ ((__visibility__("default"))) #endif #include "compatibility.h" diff --git a/include/functional_set.h b/include/functional_set.h new file mode 100644 index 0000000..e31c55e --- /dev/null +++ b/include/functional_set.h @@ -0,0 +1,131 @@ +// MIT License +// +// Copyright (c) 2022 Ioannis Kaliakatsos +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once +#include +#include +//#include +//#include "index_range.h" +//#include "optional.h" +//#ifdef PARALLEL_ALGORITHM_AVAILABLE +//#include +//#endif + +// A lightweight wrapper around std::set, enabling fluent and functional +// programming on the set itself, rather than using the more procedural style +// of the standard library algorithms. +// +// Member functions can be mutating (eg. my_set.insert()) or +// non-mutating (eg. my_vector.inserting()) enforcing thread safety if needed +template +class functional_set +{ +public: + functional_set() + : backing_set_() + { + } + + explicit functional_set(const std::set& set) + : backing_set_(set) + { + } +// +// explicit functional_set(std::set&& set) +// : backing_set_(std::move(vector)) +// { +// } +// +// explicit functional_set(std::initializer_list list) +// : backing_set_(std::move(list)) +// { +// } + +// // Creates a new vector by repeating a given element. +// // +// // example: +// // const functional_vector filled_vector(3, "John"); +// // +// // outcome: +// // filled_vector -> functional_vector({ "John", "John", "John" }) +// explicit functional_vector(size_t count, const T& element) +// : backing_vector_(count, element) +// { +// } +// +// // Performs the functional `map` algorithm, in which every element of the resulting vector is the +// // output of applying the transform function on every element of this instance. +// // +// // example: +// // const functional_vector input_vector({ 1, 3, -5 }); +// // const auto output_vector = input_vector.map([](const auto& element) { +// // return std::to_string(element); +// // }); +// // +// // outcome: +// // output_vector -> functional_vector({ "1", "3", "-5" }) +// // +// // is equivalent to: +// // const functional_vector input_vector({ 1, 3, -5 }); +// // functional_vector output_vector; +// // for (auto i = 0; i < input_vector.size(); ++i) { +// // output_vector.insert_back(std::to_string(input_vector[i])); +// // } +//#ifdef CPP17_AVAILABLE +// template >> +//#else +// template +//#endif + + // Returns the size of the vector (how many elements it contains, it may be different from its capacity) + size_t size() const + { + return backing_set_.size(); + } + + // Returns the begin iterator, useful for other standard library algorithms + [[nodiscard]] typename std::set::iterator begin() + { + return backing_set_.begin(); + } + + // Returns the const begin iterator, useful for other standard library algorithms + [[nodiscard]] typename std::set::const_iterator cbegin() const + { + return backing_set_.begin(); + } + + // Returns the end iterator, useful for other standard library algorithms + [[nodiscard]] typename std::set::iterator end() + { + return backing_set_.end(); + } + + // Returns the const end iterator, useful for other standard library algorithms + [[nodiscard]] typename std::set::const_iterator cend() const + { + return backing_set_.end(); + } + +private: + std::set backing_set_; +}; diff --git a/include/functional_vector.h b/include/functional_vector.h index c65b098..00837d4 100644 --- a/include/functional_vector.h +++ b/include/functional_vector.h @@ -54,6 +54,7 @@ class functional_vector : backing_vector_(std::move(vector)) { } + explicit functional_vector(std::initializer_list list) : backing_vector_(std::move(list)) { diff --git a/include/index_range.h b/include/index_range.h index 7c82a4e..b1cbf3f 100644 --- a/include/index_range.h +++ b/include/index_range.h @@ -24,7 +24,7 @@ #include "export_def.h" // A struct used for container safe access based on index -struct FunctionalVectorExport index_range +struct FunctionalCppExport index_range { // Used for returning values of invalid operations static index_range invalid; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9af57e6..e657fde 100755 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,4 +1,4 @@ -set (LIBNAME functional_vector) +set (LIBNAME functional_cpp) # Properties->C/C++->General->Additional Include Directories include_directories ("../include") @@ -24,7 +24,7 @@ target_link_libraries(${LIBNAME} PUBLIC tbb) endif() # creates preprocessor definition used for library exports -add_compile_definitions("FUNCTIONAL_VECTOR_EXPORTS") +add_compile_definitions("FUNCTIONAL_CPP_EXPORTS") set_target_properties(${LIBNAME} PROPERTIES OUTPUT_NAME ${LIBNAME} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 0d3a07b..78514b3 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -16,7 +16,7 @@ file (GLOB TEST_SOURCES add_executable (${EXENAME} ${TEST_SOURCES}) # Properties->Linker->Input->Additional Dependencies -target_link_libraries(${EXENAME} PUBLIC functional_vector gtest_main) +target_link_libraries(${EXENAME} PUBLIC functional_cpp gtest_main) # Creates a folder "executables" and adds target project under it set_property(TARGET ${EXENAME} PROPERTY FOLDER "executables") diff --git a/tests/functional_set_test.cc b/tests/functional_set_test.cc new file mode 100644 index 0000000..b82fcf2 --- /dev/null +++ b/tests/functional_set_test.cc @@ -0,0 +1,50 @@ +// MIT License +// +// Copyright (c) 2022 Ioannis Kaliakatsos +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#include +#include "warnings.h" +#include "functional_set.h" + +template +void debug(functional_set& set) +{ + std::cout << "bla" << std::endl; + for (auto &x : set) { + std::cout << x << std::endl; + } +// set.for_each([](const T& element) { +// std::cout << element << std::endl; +// }); +} + +TEST(FunctionalSetTest, EmptyConstructor) +{ + functional_set set_under_test; + EXPECT_EQ(0, set_under_test.size()); +} + +TEST(FunctionalSetTest, StdSetConstructor) +{ + functional_set set_under_test(std::set({1, 2, 3, 5})); + debug(set_under_test); + EXPECT_EQ(4, set_under_test.size()); +} diff --git a/tests/functional_vector_test.cc b/tests/functional_vector_test.cc index c18707a..d4c8b7c 100644 --- a/tests/functional_vector_test.cc +++ b/tests/functional_vector_test.cc @@ -21,51 +21,14 @@ // SOFTWARE. #include -#include #include #include "functional_vector.h" #include "index_range.h" - -#ifdef _MSC_VER -#pragma warning(disable: 4834) // discarding return value of function with 'nodiscard' attribute -#pragma warning(disable: 4100) // unreferenced formal parameter -#pragma warning(disable: 4018) // signed/unsigned mismatch -#pragma warning(disable: 4389) // signed/unsigned mismatch -#endif - -struct child -{ - child() - : age(0) - { - } - - child(int age) - : age(age) - { - } - - int age; -}; - -struct person -{ - person() - : age(0), name("") - { - } - - person(int age, std::string name) - : age(age), name(std::move(name)) - { - } - - int age; - std::string name; -}; +#include "test_types.h" +#include "warnings.h" template -void debug_vector(const functional_vector& vec) +void debug(const functional_vector& vec) { vec.for_each([](const T& element) { std::cout << element << std::endl; diff --git a/tests/test_types.h b/tests/test_types.h new file mode 100644 index 0000000..82e5fb3 --- /dev/null +++ b/tests/test_types.h @@ -0,0 +1,55 @@ +// MIT License +// +// Copyright (c) 2022 Ioannis Kaliakatsos +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once +#include + +struct child +{ + child() + : age(0) + { + } + + child(int age) + : age(age) + { + } + + int age; +}; + +struct person +{ + person() + : age(0), name("") + { + } + + person(int age, std::string name) + : age(age), name(std::move(name)) + { + } + + int age; + std::string name; +}; diff --git a/tests/warnings.h b/tests/warnings.h new file mode 100644 index 0000000..85046f9 --- /dev/null +++ b/tests/warnings.h @@ -0,0 +1,30 @@ +// MIT License +// +// Copyright (c) 2022 Ioannis Kaliakatsos +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#ifdef _MSC_VER +#pragma warning(disable: 4834) // discarding return value of function with 'nodiscard' attribute +#pragma warning(disable: 4100) // unreferenced formal parameter +#pragma warning(disable: 4018) // signed/unsigned mismatch +#pragma warning(disable: 4389) // signed/unsigned mismatch +#endif From 9c3cc30aeb7262169b6fffafac0465861022e12d Mon Sep 17 00:00:00 2001 From: jkaliak Date: Mon, 4 Jul 2022 22:38:58 +0200 Subject: [PATCH 04/44] Function comments on what needs to be implemented and implemented operator[] --- include/functional_set.h | 129 +++++++++++++++++++++++------------ tests/functional_set_test.cc | 21 +++++- 2 files changed, 102 insertions(+), 48 deletions(-) diff --git a/include/functional_set.h b/include/functional_set.h index e31c55e..46b9d3c 100644 --- a/include/functional_set.h +++ b/include/functional_set.h @@ -49,52 +49,40 @@ class functional_set : backing_set_(set) { } -// -// explicit functional_set(std::set&& set) -// : backing_set_(std::move(vector)) -// { -// } -// -// explicit functional_set(std::initializer_list list) -// : backing_set_(std::move(list)) -// { -// } -// // Creates a new vector by repeating a given element. -// // -// // example: -// // const functional_vector filled_vector(3, "John"); -// // -// // outcome: -// // filled_vector -> functional_vector({ "John", "John", "John" }) -// explicit functional_vector(size_t count, const T& element) -// : backing_vector_(count, element) -// { -// } -// -// // Performs the functional `map` algorithm, in which every element of the resulting vector is the -// // output of applying the transform function on every element of this instance. -// // -// // example: -// // const functional_vector input_vector({ 1, 3, -5 }); -// // const auto output_vector = input_vector.map([](const auto& element) { -// // return std::to_string(element); -// // }); -// // -// // outcome: -// // output_vector -> functional_vector({ "1", "3", "-5" }) -// // -// // is equivalent to: -// // const functional_vector input_vector({ 1, 3, -5 }); -// // functional_vector output_vector; -// // for (auto i = 0; i < input_vector.size(); ++i) { -// // output_vector.insert_back(std::to_string(input_vector[i])); -// // } -//#ifdef CPP17_AVAILABLE -// template >> -//#else -// template -//#endif + // ctor from std::vector + // ctor from functional_vector + // ctor from initializer_list + // difference + // union + // intersection + // min + // max + // map algorithm + // map parallel algorithm + // all_of + // all_of_parallel + // any_of + // any_of_parallel + // none_of + // none_of_parallel + // filter + // filter_parallel + // filtered + // filtered_parallel + // zip with functional_vector + // zip with functional_set + // zip with std::vector + // zip with std::set + // for_each -> test + // for_each_parallel + // remove + // removing + // insert + // inserting + // cleared + // contains + // find // Returns the size of the vector (how many elements it contains, it may be different from its capacity) size_t size() const @@ -102,6 +90,11 @@ class functional_set return backing_set_.size(); } + // clear + // is_empty + // capacity + // reserve + // Returns the begin iterator, useful for other standard library algorithms [[nodiscard]] typename std::set::iterator begin() { @@ -125,7 +118,53 @@ class functional_set { return backing_set_.end(); } + + // Returns the given key in the current set, allowing subscripting. + // Bounds checking (assert) is enabled for debug builds. + // Performance is O(n), so be careful for performance critical code sections. + T operator[](int index) + { + assert_smaller_size(index); +#ifdef CPP17_AVAILABLE + auto it = std::advance(begin(), index); + return *it; +#else + auto count = 0; + auto it = begin(); + while (count++ < index) { + it++; + } + return *it; +#endif + } + + // Returns the given key in the current constant set, allowing subscripting. + // Bounds checking (assert) is enabled for debug builds. + // Performance is O(n), so be careful for performance critical code sections. + T operator[](int index) const + { + assert_smaller_size(index); +#ifdef CPP17_AVAILABLE + auto it = std::advance(begin(), index); + return *it; +#else + auto count = 0; + auto it = cbegin(); + while (count++ < index) { + it++; + } + return *it; +#endif + } + + // == + // != private: std::set backing_set_; + + void assert_smaller_size(int index) const + { + assert(index < size() && index >= 0); + } }; diff --git a/tests/functional_set_test.cc b/tests/functional_set_test.cc index b82fcf2..bb9b1c2 100644 --- a/tests/functional_set_test.cc +++ b/tests/functional_set_test.cc @@ -44,7 +44,22 @@ TEST(FunctionalSetTest, EmptyConstructor) TEST(FunctionalSetTest, StdSetConstructor) { - functional_set set_under_test(std::set({1, 2, 3, 5})); - debug(set_under_test); - EXPECT_EQ(4, set_under_test.size()); + functional_set set_under_test(std::set({1, 5, 3, 3})); + EXPECT_EQ(3, set_under_test.size()); +} + +TEST(FunctionalSetTest, Subscripting) +{ + functional_set set_under_test(std::set({1, 5, 3, 3})); + EXPECT_EQ(1, set_under_test[0]); + EXPECT_EQ(3, set_under_test[1]); + EXPECT_EQ(5, set_under_test[2]); +} + +TEST(FunctionalSetTest, ConstSubscripting) +{ + const functional_set set_under_test(std::set({1, 5, 3, 3})); + EXPECT_EQ(1, set_under_test[0]); + EXPECT_EQ(3, set_under_test[1]); + EXPECT_EQ(5, set_under_test[2]); } From b5973e9b525b0b66518918b87c32a1801dd56ac6 Mon Sep 17 00:00:00 2001 From: jkaliak Date: Mon, 4 Jul 2022 22:50:22 +0200 Subject: [PATCH 05/44] Implemented all constructors --- include/functional_set.h | 27 ++++++++++++++++++--------- tests/functional_set_test.cc | 36 +++++++++++++++++++++++++++++------- 2 files changed, 47 insertions(+), 16 deletions(-) diff --git a/include/functional_set.h b/include/functional_set.h index 46b9d3c..ee1af2a 100644 --- a/include/functional_set.h +++ b/include/functional_set.h @@ -23,12 +23,9 @@ #pragma once #include #include -//#include -//#include "index_range.h" -//#include "optional.h" -//#ifdef PARALLEL_ALGORITHM_AVAILABLE -//#include -//#endif + +template +class functional_vector; // A lightweight wrapper around std::set, enabling fluent and functional // programming on the set itself, rather than using the more procedural style @@ -50,9 +47,21 @@ class functional_set { } - // ctor from std::vector - // ctor from functional_vector - // ctor from initializer_list + explicit functional_set(const std::vector& vector) + : backing_set_(vector.begin(), vector.end()) + { + } + + explicit functional_set(const functional_vector& vector) + : backing_set_(vector.cbegin(), vector.cend()) + { + } + + explicit functional_set(const std::initializer_list& list) + : backing_set_(list.begin(), list.end()) + { + } + // difference // union // intersection diff --git a/tests/functional_set_test.cc b/tests/functional_set_test.cc index bb9b1c2..0c0691b 100644 --- a/tests/functional_set_test.cc +++ b/tests/functional_set_test.cc @@ -23,6 +23,7 @@ #include #include "warnings.h" #include "functional_set.h" +#include "functional_vector.h" template void debug(functional_set& set) @@ -36,6 +37,13 @@ void debug(functional_set& set) // }); } +void testContents(const functional_set& set) { + EXPECT_EQ(3, set.size()); + EXPECT_EQ(1, set[0]); + EXPECT_EQ(3, set[1]); + EXPECT_EQ(5, set[2]); +} + TEST(FunctionalSetTest, EmptyConstructor) { functional_set set_under_test; @@ -45,21 +53,35 @@ TEST(FunctionalSetTest, EmptyConstructor) TEST(FunctionalSetTest, StdSetConstructor) { functional_set set_under_test(std::set({1, 5, 3, 3})); - EXPECT_EQ(3, set_under_test.size()); + testContents(set_under_test); +} + +TEST(FunctionalSetTest, StdVectorConstructor) +{ + functional_set set_under_test(std::vector({1, 5, 3, 3})); + testContents(set_under_test); +} + +TEST(FunctionalSetTest, FunctionalVectorConstructor) +{ + functional_set set_under_test(functional_vector({1, 5, 3, 3})); + testContents(set_under_test); +} + +TEST(FunctionalSetTest, StdInitializerListConstructor) +{ + functional_set set_under_test(std::initializer_list({1, 5, 3, 3})); + testContents(set_under_test); } TEST(FunctionalSetTest, Subscripting) { functional_set set_under_test(std::set({1, 5, 3, 3})); - EXPECT_EQ(1, set_under_test[0]); - EXPECT_EQ(3, set_under_test[1]); - EXPECT_EQ(5, set_under_test[2]); + testContents(set_under_test); } TEST(FunctionalSetTest, ConstSubscripting) { const functional_set set_under_test(std::set({1, 5, 3, 3})); - EXPECT_EQ(1, set_under_test[0]); - EXPECT_EQ(3, set_under_test[1]); - EXPECT_EQ(5, set_under_test[2]); + testContents(set_under_test); } From 40758b50afb9e422caf858209baf11b801dab738 Mon Sep 17 00:00:00 2001 From: jkaliak Date: Mon, 4 Jul 2022 23:06:58 +0200 Subject: [PATCH 06/44] Set difference implemented --- include/functional_set.h | 22 +++++++++++++++++++++- tests/functional_set_test.cc | 11 +++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/include/functional_set.h b/include/functional_set.h index ee1af2a..b5632bb 100644 --- a/include/functional_set.h +++ b/include/functional_set.h @@ -62,7 +62,27 @@ class functional_set { } - // difference + // Returns the set of elements which belong only to the current set and not in "other". + // In Venn diagram notation, if A is the current set and B is the "other" set, then + // the difference is the operation A – B = {x : x ∈ A and x ∉ B} + // + // example: + // const functional_set set1(std::set({1, 2, 3, 5, 7, 8, 10})); + // const functional_set set2(std::set({2, 5, 7, 10, 15, 17})); + // const auto& diff = set1.difference(set2); + // + // outcome: + // diff -> functional_set(1, 3, 8) + functional_set difference(const functional_set& other) const { + std::set diff; + std::set_difference(cbegin(), + cend(), + other.cbegin(), + other.cend(), + std::inserter(diff, diff.begin())); + return functional_set(diff); + } + // union // intersection // min diff --git a/tests/functional_set_test.cc b/tests/functional_set_test.cc index 0c0691b..7841b4e 100644 --- a/tests/functional_set_test.cc +++ b/tests/functional_set_test.cc @@ -85,3 +85,14 @@ TEST(FunctionalSetTest, ConstSubscripting) const functional_set set_under_test(std::set({1, 5, 3, 3})); testContents(set_under_test); } + +TEST(FunctionalSetTest, Difference) +{ + const functional_set set1(std::set({1, 2, 3, 5, 7, 8, 10})); + const functional_set set2(std::set({2, 5, 7, 10, 15, 17})); + const auto& diff = set1.difference(set2); + EXPECT_EQ(3, diff.size()); + EXPECT_EQ(1, diff[0]); + EXPECT_EQ(3, diff[1]); + EXPECT_EQ(8, diff[2]); +} From 531e17e02ab1900d51cc8d941af37d3ee8327556 Mon Sep 17 00:00:00 2001 From: jkaliak Date: Mon, 4 Jul 2022 23:37:10 +0200 Subject: [PATCH 07/44] set operations --- include/functional_vector.h | 6 +++-- tests/functional_set_test.cc | 45 ++++++++++++++++++++++++++++++++---- 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/include/functional_vector.h b/include/functional_vector.h index 00837d4..12488e6 100644 --- a/include/functional_vector.h +++ b/include/functional_vector.h @@ -1451,19 +1451,21 @@ class functional_vector bool operator ==(const functional_vector& rhs) const { #ifdef CPP17_AVAILABLE - return std::equal(backing_vector_.cbegin(), - backing_vector_.cend(), + return std::equal(cbegin(), + cend(), rhs.cbegin(), rhs.cend()); #else if (size() != rhs.size()) { return false; } + for (auto i = 0; i < size(); ++i) { if ((*this)[i] != rhs[i]) { return false; } } + return true; #endif } diff --git a/tests/functional_set_test.cc b/tests/functional_set_test.cc index 7841b4e..85338ea 100644 --- a/tests/functional_set_test.cc +++ b/tests/functional_set_test.cc @@ -91,8 +91,45 @@ TEST(FunctionalSetTest, Difference) const functional_set set1(std::set({1, 2, 3, 5, 7, 8, 10})); const functional_set set2(std::set({2, 5, 7, 10, 15, 17})); const auto& diff = set1.difference(set2); - EXPECT_EQ(3, diff.size()); - EXPECT_EQ(1, diff[0]); - EXPECT_EQ(3, diff[1]); - EXPECT_EQ(8, diff[2]); + EXPECT_EQ(functional_set({1, 3, 8}), diff); +} + +TEST(FunctionalSetTest, DifferenceStdSet) +{ + const functional_set set1(std::set({1, 2, 3, 5, 7, 8, 10})); + const std::set set2({2, 5, 7, 10, 15, 17}); + const auto& diff = set1.difference(set2); + EXPECT_EQ(functional_set({1, 3, 8}), diff); +} + +TEST(FunctionalSetTest, Union) +{ + const functional_set set1(std::set({1, 2, 3, 5, 7, 8, 10})); + const functional_set set2(std::set({2, 5, 7, 10, 15, 17})); + const auto& combined = set1.union_with(set2); + EXPECT_EQ(functional_set({1, 2, 3, 5, 7, 8, 10, 15, 17}), combined); +} + +TEST(FunctionalSetTest, UnionStdSet) +{ + const functional_set set1(std::set({1, 2, 3, 5, 7, 8, 10})); + const std::set set2({2, 5, 7, 10, 15, 17}); + const auto& combined = set1.union_with(set2); + EXPECT_EQ(functional_set({1, 2, 3, 5, 7, 8, 10, 15, 17}), combined); +} + +TEST(FunctionalSetTest, Intersection) +{ + const functional_set set1(std::set({1, 2, 3, 5, 7, 8, 10})); + const functional_set set2(std::set({2, 5, 7, 10, 15, 17})); + const auto& intersection = set1.intersect_with(set2); + EXPECT_EQ(functional_set({2, 5, 7, 10}), intersection); +} + +TEST(FunctionalSetTest, IntersectionStdSet) +{ + const functional_set set1(std::set({1, 2, 3, 5, 7, 8, 10})); + const std::set set2({2, 5, 7, 10, 15, 17}); + const auto& intersection = set1.intersect_with(set2); + EXPECT_EQ(functional_set({2, 5, 7, 10}), intersection); } From dbbb3c99cf19499532089d3aff74e82be99e4678 Mon Sep 17 00:00:00 2001 From: jkaliak Date: Mon, 4 Jul 2022 23:37:26 +0200 Subject: [PATCH 08/44] Update functional_set.h --- include/functional_set.h | 94 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 86 insertions(+), 8 deletions(-) diff --git a/include/functional_set.h b/include/functional_set.h index b5632bb..2184928 100644 --- a/include/functional_set.h +++ b/include/functional_set.h @@ -41,7 +41,7 @@ class functional_set : backing_set_() { } - + explicit functional_set(const std::set& set) : backing_set_(set) { @@ -62,8 +62,8 @@ class functional_set { } - // Returns the set of elements which belong only to the current set and not in "other". - // In Venn diagram notation, if A is the current set and B is the "other" set, then + // Returns the set of elements which belong to the current set but not in the other set. + // In Venn diagram notation, if A is the current set and B is the other set, then // the difference is the operation A – B = {x : x ∈ A and x ∉ B} // // example: @@ -72,7 +72,7 @@ class functional_set // const auto& diff = set1.difference(set2); // // outcome: - // diff -> functional_set(1, 3, 8) + // diff -> functional_set({1, 3, 8}) functional_set difference(const functional_set& other) const { std::set diff; std::set_difference(cbegin(), @@ -83,8 +83,60 @@ class functional_set return functional_set(diff); } - // union - // intersection + functional_set difference(const std::set& other) const { + return difference(functional_set(other)); + } + + // Returns the set of elements which belong either to the current or the other set. + // In Venn diagram notation, if A is the current set and B is the other set, then + // the union is the operation A ∪ B = {x : x ∈ A or x ∈ B} + // + // example: + // const functional_set set1(std::set({1, 2, 3, 5, 7, 8, 10})); + // const functional_set set2(std::set({2, 5, 7, 10, 15, 17})); + // const auto& combined = set1.set_union(set2); + // + // outcome: + // combined -> functional_set({1, 2, 3, 5, 7, 8, 10, 15, 17}) + functional_set union_with(const functional_set& other) const { + std::set combined; + std::set_union(cbegin(), + cend(), + other.cbegin(), + other.cend(), + std::inserter(combined, combined.begin())); + return functional_set(combined); + } + + functional_set union_with(const std::set& other) const { + return union_with(functional_set(other)); + } + + // Returns the set of elements which belong to both the current and the other set. + // In Venn diagram notation, if A is the current set and B is the other set, then + // the intersection is the operation A ∩ B = {x : x ∈ A and x ∈ B} + // + // example: + // const functional_set set1(std::set({1, 2, 3, 5, 7, 8, 10})); + // const functional_set set2(std::set({2, 5, 7, 10, 15, 17})); + // const auto& combined = set1.set_union(set2); + // + // outcome: + // combined -> functional_set({2, 5, 7, 10}) + functional_set intersect_with(const functional_set& other) const { + std::set intersection; + std::set_intersection(cbegin(), + cend(), + other.cbegin(), + other.cend(), + std::inserter(intersection, intersection.begin())); + return functional_set(intersection); + } + + functional_set intersect_with(const std::set& other) const { + return intersect_with(functional_set(other)); + } + // min // max // map algorithm @@ -186,9 +238,35 @@ class functional_set #endif } - // == + // Returns true if both instances have equal sizes and the corresponding elements (keys) are equal + bool operator ==(const functional_set& rhs) const + { +#ifdef CPP17_AVAILABLE + return std::equal(cbegin(), + cend(), + rhs.cbegin(), + rhs.cend()); +#else + if (size() != rhs.size()) { + return false; + } + + auto it1 = cbegin(); + auto it2 = rhs.cbegin(); + while (it1 != cend() && it2 != rhs.cend()) { + if (*it1 != *it2) { + return false; + } + it1++; + it2++; + } + + return true; +#endif + } + // != - + private: std::set backing_set_; From e34b0e441ca3ceaca55449d43a84180433a5db72 Mon Sep 17 00:00:00 2001 From: jkaliak Date: Tue, 5 Jul 2022 22:00:35 +0200 Subject: [PATCH 09/44] set inequality operator, distinct elements from vector --- include/functional_set.h | 6 +++++- include/functional_vector.h | 17 ++++++++++++++++- tests/functional_set_test.cc | 16 ++++++++++++++++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/include/functional_set.h b/include/functional_set.h index 2184928..ba2f5c5 100644 --- a/include/functional_set.h +++ b/include/functional_set.h @@ -265,7 +265,11 @@ class functional_set #endif } - // != + // Returns false if either the sizes are not equal or at least one corresponding element (key) is not equal + bool operator !=(const functional_set& rhs) const + { + return !((*this) == rhs); + } private: std::set backing_set_; diff --git a/include/functional_vector.h b/include/functional_vector.h index 12488e6..abd620c 100644 --- a/include/functional_vector.h +++ b/include/functional_vector.h @@ -30,6 +30,9 @@ #include #endif +template +class functional_set; + // A lightweight wrapper around std::vector, enabling fluent and functional // programming on the vector itself, rather than using the more procedural style // of the standard library algorithms. @@ -1431,6 +1434,18 @@ class functional_vector return backing_vector_.end(); } + // Returns a set, whose elements are the elements of the vector, removing any potential duplicates + // + // example: + // const functional_vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); + // const auto& unique_numbers = numbers.distinct(); + // + // outcome: + // unique_numbers -> functional_set({1, 2, 3, 4, 5, 7, 8}) + functional_set distinct() const { + return functional_set(*this); + } + // Returns a reference to the element in the given index, allowing subscripting and value editing. // Bounds checking (assert) is enabled for debug builds. T& operator[](int index) @@ -1470,7 +1485,7 @@ class functional_vector #endif } - // Returns false if either the sizes are not equal or at least corresponding element (same index) is not equal + // Returns false if either the sizes are not equal or at least one corresponding element (same index) is not equal bool operator !=(const functional_vector& rhs) const { return !((*this) == rhs); diff --git a/tests/functional_set_test.cc b/tests/functional_set_test.cc index 85338ea..d2a5a19 100644 --- a/tests/functional_set_test.cc +++ b/tests/functional_set_test.cc @@ -133,3 +133,19 @@ TEST(FunctionalSetTest, IntersectionStdSet) const auto& intersection = set1.intersect_with(set2); EXPECT_EQ(functional_set({2, 5, 7, 10}), intersection); } + +TEST(FunctionalSetTest, EqualityOperator) +{ + const functional_set set1(std::set({1, 2, 3})); + const functional_set set2(std::set({1, 2, 3, 2, 3})); + EXPECT_TRUE(set1 == set2); + EXPECT_FALSE(set1 != set2); +} + +TEST(FunctionalSetTest, InequalityOperator) +{ + const functional_set set1(std::set({1, 2, 3})); + const functional_set set2(std::set({1, 2, 3, 4})); + EXPECT_FALSE(set1 == set2); + EXPECT_TRUE(set1 != set2); +} From ec0645cb2ec6378fff75dcbfa0581204d842825b Mon Sep 17 00:00:00 2001 From: jkaliak Date: Tue, 5 Jul 2022 22:00:43 +0200 Subject: [PATCH 10/44] Update functional_vector_test.cc --- tests/functional_vector_test.cc | 266 ++++++++++++++++---------------- 1 file changed, 137 insertions(+), 129 deletions(-) diff --git a/tests/functional_vector_test.cc b/tests/functional_vector_test.cc index d4c8b7c..92baf0f 100644 --- a/tests/functional_vector_test.cc +++ b/tests/functional_vector_test.cc @@ -23,6 +23,7 @@ #include #include #include "functional_vector.h" +#include "functional_set.h" #include "index_range.h" #include "test_types.h" #include "warnings.h" @@ -35,7 +36,7 @@ void debug(const functional_vector& vec) }); } -TEST(FunctionalVectorTest, InsertBackTest) +TEST(FunctionalVectorTest, InsertBack) { functional_vector vector_under_test; EXPECT_EQ(0, vector_under_test.size()); @@ -50,7 +51,7 @@ TEST(FunctionalVectorTest, InsertBackTest) EXPECT_EQ(-1, vector_under_test[1]); } -TEST(FunctionalVectorTest, InsertFrontTest) +TEST(FunctionalVectorTest, InsertFront) { functional_vector vector_under_test; EXPECT_EQ(0, vector_under_test.size()); @@ -65,7 +66,7 @@ TEST(FunctionalVectorTest, InsertFrontTest) EXPECT_EQ(5, vector_under_test[1]); } -TEST(FunctionalVectorTest, InsertingBackTest) +TEST(FunctionalVectorTest, InsertingBack) { const functional_vector vector_under_test({3, 6, 2, 8}); const auto vector_new_instance = vector_under_test.inserting_back(5); @@ -75,7 +76,7 @@ TEST(FunctionalVectorTest, InsertingBackTest) EXPECT_EQ(functional_vector({ 3, 6, 2, 8, 5 }), vector_new_instance); } -TEST(FunctionalVectorTest, InsertingFrontTest) +TEST(FunctionalVectorTest, InsertingFront) { const functional_vector vector_under_test({3, 6, 2, 8}); const auto vector_new_instance = vector_under_test.inserting_front(5); @@ -85,49 +86,49 @@ TEST(FunctionalVectorTest, InsertingFrontTest) EXPECT_EQ(functional_vector({ 5, 3, 6, 2, 8}), vector_new_instance); } -TEST(FunctionalVectorTest, InsertBackFromFunctionalVectorTest) +TEST(FunctionalVectorTest, InsertBackFromFunctionalVector) { functional_vector vector_under_test({ 4, 5, 6 }); vector_under_test.insert_back(functional_vector({1, 2, 3})); EXPECT_EQ(functional_vector({ 4, 5, 6, 1, 2, 3 }), vector_under_test); } -TEST(FunctionalVectorTest, InsertBackFromStdVectorTest) +TEST(FunctionalVectorTest, InsertBackFromStdVector) { functional_vector vector_under_test({ 4, 5, 6 }); vector_under_test.insert_back(std::vector{ 1, 2, 3 }); EXPECT_EQ(functional_vector({ 4, 5, 6, 1, 2, 3 }), vector_under_test); } -TEST(FunctionalVectorTest, InsertBackFromInitializerListTest) +TEST(FunctionalVectorTest, InsertBackFromInitializerList) { functional_vector vector_under_test({ 4, 5, 6 }); vector_under_test.insert_back(std::initializer_list{ 1, 2, 3 }); EXPECT_EQ(functional_vector({ 4, 5, 6, 1, 2, 3 }), vector_under_test); } -TEST(FunctionalVectorTest, InsertFrontFromFunctionalVectorTest) +TEST(FunctionalVectorTest, InsertFrontFromFunctionalVector) { functional_vector vector_under_test({ 4, 5, 6 }); vector_under_test.insert_front(functional_vector({1, 2, 3})); EXPECT_EQ(functional_vector({ 1, 2, 3, 4, 5, 6 }), vector_under_test); } -TEST(FunctionalVectorTest, InsertFrontFromStdVectorTest) +TEST(FunctionalVectorTest, InsertFrontFromStdVector) { functional_vector vector_under_test({ 4, 5, 6 }); vector_under_test.insert_front(std::vector{ 1, 2, 3 }); EXPECT_EQ(functional_vector({ 1, 2, 3, 4, 5, 6 }), vector_under_test); } -TEST(FunctionalVectorTest, InsertFrontFromInitializerListTest) +TEST(FunctionalVectorTest, InsertFrontFromInitializerList) { functional_vector vector_under_test({ 4, 5, 6 }); vector_under_test.insert_front(std::initializer_list{ 1, 2, 3 }); EXPECT_EQ(functional_vector({ 1, 2, 3, 4, 5, 6 }), vector_under_test); } -TEST(FunctionalVectorTest, InsertingBackFromFunctionalVectorTest) +TEST(FunctionalVectorTest, InsertingBackFromFunctionalVector) { const functional_vector vector_under_test({ 4, 5, 6 }); const auto vector_new_instance = vector_under_test.inserting_back(functional_vector({1, 2, 3})); @@ -135,7 +136,7 @@ TEST(FunctionalVectorTest, InsertingBackFromFunctionalVectorTest) EXPECT_EQ(functional_vector({ 4, 5, 6, 1, 2, 3 }), vector_new_instance); } -TEST(FunctionalVectorTest, InsertingBackFromStdVectorTest) +TEST(FunctionalVectorTest, InsertingBackFromStdVector) { const functional_vector vector_under_test({ 4, 5, 6 }); const auto vector_new_instance = vector_under_test.inserting_back(std::vector{ 1, 2, 3 }); @@ -143,7 +144,7 @@ TEST(FunctionalVectorTest, InsertingBackFromStdVectorTest) EXPECT_EQ(functional_vector({ 4, 5, 6, 1, 2, 3 }), vector_new_instance); } -TEST(FunctionalVectorTest, InsertingBackFromInitializerListTest) +TEST(FunctionalVectorTest, InsertingBackFromInitializerList) { const functional_vector vector_under_test({ 4, 5, 6 }); const auto vector_new_instance = vector_under_test.inserting_back(std::initializer_list{ 1, 2, 3 }); @@ -151,7 +152,7 @@ TEST(FunctionalVectorTest, InsertingBackFromInitializerListTest) EXPECT_EQ(functional_vector({ 4, 5, 6, 1, 2, 3 }), vector_new_instance); } -TEST(FunctionalVectorTest, InsertingFrontFromFunctionalVectorTest) +TEST(FunctionalVectorTest, InsertingFrontFromFunctionalVector) { const functional_vector vector_under_test({ 4, 5, 6 }); const auto vector_new_instance = vector_under_test.inserting_front(functional_vector({1, 2, 3})); @@ -159,7 +160,7 @@ TEST(FunctionalVectorTest, InsertingFrontFromFunctionalVectorTest) EXPECT_EQ(functional_vector({ 1, 2, 3, 4, 5, 6 }), vector_new_instance); } -TEST(FunctionalVectorTest, InsertingFrontFromStdVectorTest) +TEST(FunctionalVectorTest, InsertingFrontFromStdVector) { const functional_vector vector_under_test({ 4, 5, 6 }); const auto vector_new_instance = vector_under_test.inserting_front(std::vector{ 1, 2, 3 }); @@ -167,7 +168,7 @@ TEST(FunctionalVectorTest, InsertingFrontFromStdVectorTest) EXPECT_EQ(functional_vector({ 1, 2, 3, 4, 5, 6 }), vector_new_instance); } -TEST(FunctionalVectorTest, InsertingFrontFromInitializerListTest) +TEST(FunctionalVectorTest, InsertingFrontFromInitializerList) { const functional_vector vector_under_test({ 4, 5, 6 }); const auto vector_new_instance = vector_under_test.inserting_front(std::initializer_list{ 1, 2, 3 }); @@ -175,7 +176,7 @@ TEST(FunctionalVectorTest, InsertingFrontFromInitializerListTest) EXPECT_EQ(functional_vector({ 1, 2, 3, 4, 5, 6 }), vector_new_instance); } -TEST(FunctionalVectorTest, MapTest) +TEST(FunctionalVectorTest, Map) { const functional_vector vector_under_test({1, 3, 4}); const auto mapped_vector = vector_under_test.map([](const int& age) { @@ -188,7 +189,7 @@ TEST(FunctionalVectorTest, MapTest) } #ifdef PARALLEL_ALGORITHM_AVAILABLE -TEST(FunctionalVectorTest, MapParallelTest) +TEST(FunctionalVectorTest, MapParallel) { const functional_vector vector_under_test({1, 3, 4}); const auto mapped_vector = vector_under_test.map_parallel([](const int& age) { @@ -201,7 +202,7 @@ TEST(FunctionalVectorTest, MapParallelTest) } #endif -TEST(FunctionalVectorTest, FilterTest) +TEST(FunctionalVectorTest, Filter) { functional_vector vector_under_test({child(1), child(3), child(4)}); vector_under_test.filter([](const child& child) { @@ -216,7 +217,7 @@ TEST(FunctionalVectorTest, FilterTest) } #ifdef PARALLEL_ALGORITHM_AVAILABLE -TEST(FunctionalVectorTest, FilterParallelTest) +TEST(FunctionalVectorTest, FilterParallel) { functional_vector vector_under_test({child(1), child(3), child(4)}); vector_under_test.filter_parallel([](const child& child) { @@ -231,7 +232,7 @@ TEST(FunctionalVectorTest, FilterParallelTest) } #endif -TEST(FunctionalVectorTest, FilteredTest) +TEST(FunctionalVectorTest, Filtered) { const functional_vector vector_under_test({child(1), child(3), child(4)}); const auto filtered_vector = vector_under_test.filtered([](const child& child) { @@ -243,7 +244,7 @@ TEST(FunctionalVectorTest, FilteredTest) } #ifdef PARALLEL_ALGORITHM_AVAILABLE -TEST(FunctionalVectorTest, FilteredParallelTest) +TEST(FunctionalVectorTest, FilteredParallel) { const functional_vector vector_under_test({child(1), child(3), child(4)}); const auto filtered_vector = vector_under_test.filtered_parallel([](const child& child) { @@ -255,7 +256,7 @@ TEST(FunctionalVectorTest, FilteredParallelTest) } #endif -TEST(FunctionalVectorTest, ReverseTest) +TEST(FunctionalVectorTest, Reverse) { functional_vector vector_under_test({child(6), child(2), child(9)}); vector_under_test.reverse(); @@ -265,7 +266,7 @@ TEST(FunctionalVectorTest, ReverseTest) EXPECT_EQ(6, vector_under_test[2].age); } -TEST(FunctionalVectorTest, ReversedTest) +TEST(FunctionalVectorTest, Reversed) { const functional_vector vector_under_test({child(6), child(2), child(9)}); const auto reversed_vector = vector_under_test.reversed(); @@ -280,20 +281,20 @@ TEST(FunctionalVectorTest, ReversedTest) EXPECT_EQ(9, vector_under_test[2].age); } -TEST(FunctionalVectorTest, ZipWithStdVectorUnequalSizesThrowsTest) +TEST(FunctionalVectorTest, ZipWithStdVectorUnequalSizesThrows) { const functional_vector ages_vector({32, 25, 53, 62}); EXPECT_DEATH({ const auto zipped_vector = ages_vector.zip(std::vector({"Jake", "Mary"})); }, ""); } -TEST(FunctionalVectorTest, ZipWithFunctionalVectorUnequalSizesThrowsTest) +TEST(FunctionalVectorTest, ZipWithFunctionalVectorUnequalSizesThrows) { const functional_vector ages_vector({32, 25, 53, 62}); const auto names_vector = functional_vector({"Jake", "Mary"}); EXPECT_DEATH({ const auto zipped_vector = ages_vector.zip(names_vector); }, ""); } -TEST(FunctionalVectorTest, ZipWithFunctionalVectorTest) +TEST(FunctionalVectorTest, ZipWithFunctionalVector) { const functional_vector ages_vector({32, 25, 53}); const functional_vector names_vector({"Jake", "Mary", "John"}); @@ -310,7 +311,7 @@ TEST(FunctionalVectorTest, ZipWithFunctionalVectorTest) EXPECT_EQ("John", zipped_vector[2].second); } -TEST(FunctionalVectorTest, ZipWithStdVectorTest) +TEST(FunctionalVectorTest, ZipWithStdVector) { const functional_vector ages_vector({32, 25, 53}); const auto zipped_vector = ages_vector.zip(std::vector{"Jake", "Mary", "John"}); @@ -326,7 +327,7 @@ TEST(FunctionalVectorTest, ZipWithStdVectorTest) EXPECT_EQ("John", zipped_vector[2].second); } -TEST(FunctionalVectorTest, ZipWithInitializerListTest) +TEST(FunctionalVectorTest, ZipWithInitializerList) { const functional_vector ages_vector({32, 25, 53}); const auto zipped_vector = ages_vector.zip(std::initializer_list{"Jake", "Mary", "John"}); @@ -342,7 +343,7 @@ TEST(FunctionalVectorTest, ZipWithInitializerListTest) EXPECT_EQ("John", zipped_vector[2].second); } -TEST(FunctionalVectorTest, SortTest) +TEST(FunctionalVectorTest, Sort) { functional_vector vector_under_test({ person(45, "Jake"), person(34, "Bob"), person(52, "Manfred"), person(8, "Alice") @@ -366,7 +367,7 @@ TEST(FunctionalVectorTest, SortTest) EXPECT_EQ(52, vector_under_test[3].age); } -TEST(FunctionalVectorTest, SortedTest) +TEST(FunctionalVectorTest, Sorted) { const functional_vector vector_under_test({ person(45, "Jake"), person(34, "Bob"), person(52, "Manfred"), person(8, "Alice") @@ -396,7 +397,7 @@ TEST(FunctionalVectorTest, SortedTest) EXPECT_EQ(52, sorted_vector[3].age); } -TEST(FunctionalVectorTest, SortAscendingTest) +TEST(FunctionalVectorTest, SortAscending) { functional_vector vector_under_test({3, 1, 9, -4}); vector_under_test.sort_ascending(); @@ -407,7 +408,7 @@ TEST(FunctionalVectorTest, SortAscendingTest) EXPECT_EQ(9, vector_under_test[3]); } -TEST(FunctionalVectorTest, SortedAscendingTest) +TEST(FunctionalVectorTest, SortedAscending) { const functional_vector vector_under_test({3, 1, 9, -4}); const auto sorted_vector = vector_under_test.sorted_ascending(); @@ -424,7 +425,7 @@ TEST(FunctionalVectorTest, SortedAscendingTest) EXPECT_EQ(9, sorted_vector[3]); } -TEST(FunctionalVectorTest, SortDescendingTest) +TEST(FunctionalVectorTest, SortDescending) { functional_vector vector_under_test({3, 1, 9, -4}); vector_under_test.sort_descending(); @@ -435,7 +436,7 @@ TEST(FunctionalVectorTest, SortDescendingTest) EXPECT_EQ(-4, vector_under_test[3]); } -TEST(FunctionalVectorTest, SortedDescendingTest) +TEST(FunctionalVectorTest, SortedDescending) { const functional_vector vector_under_test({3, 1, 9, -4}); const auto sorted_vector = vector_under_test.sorted_descending(); @@ -453,7 +454,7 @@ TEST(FunctionalVectorTest, SortedDescendingTest) } #ifdef PARALLEL_ALGORITHM_AVAILABLE -TEST(FunctionalVectorTest, SortParallelTest) +TEST(FunctionalVectorTest, SortParallel) { functional_vector vector_under_test({ person(45, "Jake"), person(34, "Bob"), person(52, "Manfred"), person(8, "Alice") @@ -476,7 +477,7 @@ TEST(FunctionalVectorTest, SortParallelTest) EXPECT_EQ(52, vector_under_test[3].age); } -TEST(FunctionalVectorTest, SortedParallelTest) +TEST(FunctionalVectorTest, SortedParallel) { const functional_vector vector_under_test({ person(45, "Jake"), person(34, "Bob"), person(52, "Manfred"), person(8, "Alice") @@ -506,7 +507,7 @@ TEST(FunctionalVectorTest, SortedParallelTest) EXPECT_EQ(52, sorted_vector[3].age); } -TEST(FunctionalVectorTest, SortAscendingParallelTest) +TEST(FunctionalVectorTest, SortAscendingParallel) { functional_vector vector_under_test({3, 1, 9, -4}); vector_under_test.sort_ascending_parallel(); @@ -517,7 +518,7 @@ TEST(FunctionalVectorTest, SortAscendingParallelTest) EXPECT_EQ(9, vector_under_test[3]); } -TEST(FunctionalVectorTest, SortedAscendingParallelTest) +TEST(FunctionalVectorTest, SortedAscendingParallel) { const functional_vector vector_under_test({3, 1, 9, -4}); const auto sorted_vector = vector_under_test.sorted_ascending_parallel(); @@ -534,7 +535,7 @@ TEST(FunctionalVectorTest, SortedAscendingParallelTest) EXPECT_EQ(9, sorted_vector[3]); } -TEST(FunctionalVectorTest, SortDescendingParallelTest) +TEST(FunctionalVectorTest, SortDescendingParallel) { functional_vector vector_under_test({3, 1, 9, -4}); vector_under_test.sort_descending_parallel(); @@ -545,7 +546,7 @@ TEST(FunctionalVectorTest, SortDescendingParallelTest) EXPECT_EQ(-4, vector_under_test[3]); } -TEST(FunctionalVectorTest, SortedDescendingParallelTest) +TEST(FunctionalVectorTest, SortedDescendingParallel) { const functional_vector vector_under_test({3, 1, 9, -4}); const auto sorted_vector = vector_under_test.sorted_descending_parallel(); @@ -563,43 +564,43 @@ TEST(FunctionalVectorTest, SortedDescendingParallelTest) } #endif -TEST(FunctionalVectorTest, SubscriptOperatorNegativeDeathTest) +TEST(FunctionalVectorTest, SubscriptOperatorNegativeDeath) { const functional_vector vector_under_test({3, 1, 9, -4}); EXPECT_DEATH(vector_under_test[-1], ""); } -TEST(FunctionalVectorTest, SubscriptOperatorIndexEqualToSizeDeathTest) +TEST(FunctionalVectorTest, SubscriptOperatorIndexEqualToSizeDeath) { const functional_vector vector_under_test({3, 1, 9, -4}); EXPECT_DEATH(vector_under_test[4], ""); } -TEST(FunctionalVectorTest, SubscriptOperatorIndexLargerThanSizeDeathTest) +TEST(FunctionalVectorTest, SubscriptOperatorIndexLargerThanSizeDeath) { const functional_vector vector_under_test({3, 1, 9, -4}); EXPECT_DEATH(vector_under_test[5], ""); } -TEST(FunctionalVectorTest, SubscriptOperatorAssignNegativeDeathTest) +TEST(FunctionalVectorTest, SubscriptOperatorAssignNegativeDeath) { functional_vector vector_under_test({3, 1, 9, -4}); EXPECT_DEATH(vector_under_test[-1] = 5, ""); } -TEST(FunctionalVectorTest, SubscriptOperatorAssignIndexEqualSizeDeathTest) +TEST(FunctionalVectorTest, SubscriptOperatorAssignIndexEqualSizeDeath) { functional_vector vector_under_test({3, 1, 9, -4}); EXPECT_DEATH(vector_under_test[4] = 5, ""); } -TEST(FunctionalVectorTest, SubscriptOperatorAssignIndexLargerThanSizeDeathTest) +TEST(FunctionalVectorTest, SubscriptOperatorAssignIndexLargerThanSizeDeath) { functional_vector vector_under_test({3, 1, 9, -4}); EXPECT_DEATH(vector_under_test[5] = -3, ""); } -TEST(FunctionalVectorTest, SubscriptOperatorAssignTest) +TEST(FunctionalVectorTest, SubscriptOperatorAssign) { functional_vector vector_under_test({3, 1, 9, -4}); vector_under_test[2] = 7; @@ -610,19 +611,19 @@ TEST(FunctionalVectorTest, SubscriptOperatorAssignTest) EXPECT_EQ(-4, vector_under_test[3]); } -TEST(FunctionalVectorTest, FindFirstIndexEmptyVectorTest) +TEST(FunctionalVectorTest, FindFirstIndexEmptyVector) { const functional_vector vector_under_test; EXPECT_FALSE(vector_under_test.find_first_index(-3).has_value()); } -TEST(FunctionalVectorTest, FindFirstIndexFilledVectorWithoutMatchTest) +TEST(FunctionalVectorTest, FindFirstIndexFilledVectorWithoutMatch) { const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_FALSE(vector_under_test.find_first_index(9).has_value()); } -TEST(FunctionalVectorTest, FindFirstIndexFilledVectorTest) +TEST(FunctionalVectorTest, FindFirstIndexFilledVector) { const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_EQ(0, vector_under_test.find_first_index(1).value()); @@ -630,19 +631,19 @@ TEST(FunctionalVectorTest, FindFirstIndexFilledVectorTest) EXPECT_EQ(3, vector_under_test.find_first_index(5).value()); } -TEST(FunctionalVectorTest, FindLastIndexEmptyVectorTest) +TEST(FunctionalVectorTest, FindLastIndexEmptyVector) { const functional_vector vector_under_test; EXPECT_FALSE(vector_under_test.find_last_index(-3).has_value()); } -TEST(FunctionalVectorTest, FindLastIndexFilledVectorWithoutMatchTest) +TEST(FunctionalVectorTest, FindLastIndexFilledVectorWithoutMatch) { const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_FALSE(vector_under_test.find_last_index(9).has_value()); } -TEST(FunctionalVectorTest, FindLastIndexFilledVectorTest) +TEST(FunctionalVectorTest, FindLastIndexFilledVector) { const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_EQ(8, vector_under_test.find_last_index(1).value()); @@ -650,19 +651,19 @@ TEST(FunctionalVectorTest, FindLastIndexFilledVectorTest) EXPECT_EQ(3, vector_under_test.find_last_index(5).value()); } -TEST(FunctionalVectorTest, FindAllIndicesEmptyVectorTest) +TEST(FunctionalVectorTest, FindAllIndicesEmptyVector) { const functional_vector vector_under_test; EXPECT_EQ(0, vector_under_test.find_all_indices(-3).size()); } -TEST(FunctionalVectorTest, FindAllIndicesFilledVectorWithoutMatchTest) +TEST(FunctionalVectorTest, FindAllIndicesFilledVectorWithoutMatch) { const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_EQ(0, vector_under_test.find_all_indices(9).size()); } -TEST(FunctionalVectorTest, FindAllIndicesFilledVectorTest) +TEST(FunctionalVectorTest, FindAllIndicesFilledVector) { const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 9, 1}); const auto one_indices = vector_under_test.find_all_indices(1); @@ -671,7 +672,7 @@ TEST(FunctionalVectorTest, FindAllIndicesFilledVectorTest) EXPECT_EQ(std::vector({ 7 }), seven_indices); } -TEST(FunctionalVectorTest, RemoveAtEmptyVectorTest) +TEST(FunctionalVectorTest, RemoveAtEmptyVector) { functional_vector vector_under_test; EXPECT_DEATH(vector_under_test.remove_at(-1), ""); @@ -679,13 +680,13 @@ TEST(FunctionalVectorTest, RemoveAtEmptyVectorTest) EXPECT_DEATH(vector_under_test.remove_at(1), ""); } -TEST(FunctionalVectorTest, RemoveAtFilledVectorAboveSizeTest) +TEST(FunctionalVectorTest, RemoveAtFilledVectorAboveSize) { auto vector_under_test = functional_vector({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_DEATH(vector_under_test.remove_at(15), ""); } -TEST(FunctionalVectorTest, RemoveAtFilledVectorTest) +TEST(FunctionalVectorTest, RemoveAtFilledVector) { functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); vector_under_test.remove_at(1); @@ -696,7 +697,7 @@ TEST(FunctionalVectorTest, RemoveAtFilledVectorTest) EXPECT_EQ(functional_vector({ 1, 5, 8, 3, 7, 1 }), vector_under_test); } -TEST(FunctionalVectorTest, RemovingAtEmptyVectorTest) +TEST(FunctionalVectorTest, RemovingAtEmptyVector) { const functional_vector vector_under_test; EXPECT_DEATH(vector_under_test.removing_at(-1), ""); @@ -704,13 +705,13 @@ TEST(FunctionalVectorTest, RemovingAtEmptyVectorTest) EXPECT_DEATH(vector_under_test.removing_at(1), ""); } -TEST(FunctionalVectorTest, RemovingAtFilledVectorAboveSizeTest) +TEST(FunctionalVectorTest, RemovingAtFilledVectorAboveSize) { const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_DEATH(vector_under_test.removing_at(15), ""); } -TEST(FunctionalVectorTest, RemovingAtFilledVectorTest) +TEST(FunctionalVectorTest, RemovingAtFilledVector) { const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); const auto shorter_vector = vector_under_test.removing_at(1); @@ -718,7 +719,7 @@ TEST(FunctionalVectorTest, RemovingAtFilledVectorTest) EXPECT_EQ(functional_vector({ 1, 4, 2, 5, 8, 3, 1, 7, 1 }), vector_under_test); } -TEST(FunctionalVectorTest, RemoveBackTest) +TEST(FunctionalVectorTest, RemoveBack) { functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); vector_under_test.remove_back(); @@ -729,7 +730,7 @@ TEST(FunctionalVectorTest, RemoveBackTest) EXPECT_EQ(functional_vector({ 1, 4, 2, 5, 8, 3 }), vector_under_test); } -TEST(FunctionalVectorTest, RemovingBackTest) +TEST(FunctionalVectorTest, RemovingBack) { const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); const auto vector_without_last_element = vector_under_test.removing_back(); @@ -737,7 +738,7 @@ TEST(FunctionalVectorTest, RemovingBackTest) EXPECT_EQ(functional_vector({ 1, 4, 2, 5, 8, 3, 1, 7, 1 }), vector_under_test); } -TEST(FunctionalVectorTest, RemoveFrontTest) +TEST(FunctionalVectorTest, RemoveFront) { functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); vector_under_test.remove_front(); @@ -748,7 +749,7 @@ TEST(FunctionalVectorTest, RemoveFrontTest) EXPECT_EQ(functional_vector({ 5, 8, 3, 1, 7, 1 }), vector_under_test); } -TEST(FunctionalVectorTest, RemovingFrontTest) +TEST(FunctionalVectorTest, RemovingFront) { const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); const auto vector_without_first_element = vector_under_test.removing_front(); @@ -757,7 +758,7 @@ TEST(FunctionalVectorTest, RemovingFrontTest) } -TEST(FunctionalVectorTest, InsertAtEmptyVectorTest) +TEST(FunctionalVectorTest, InsertAtEmptyVector) { functional_vector vector_under_test; EXPECT_DEATH(vector_under_test.insert_at(15, -1), ""); @@ -766,7 +767,7 @@ TEST(FunctionalVectorTest, InsertAtEmptyVectorTest) EXPECT_EQ(-1, vector_under_test[0]); } -TEST(FunctionalVectorTest, InsertAtFilledVectorTest) +TEST(FunctionalVectorTest, InsertAtFilledVector) { functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_DEATH(vector_under_test.insert_at(15, -1), ""); @@ -774,7 +775,7 @@ TEST(FunctionalVectorTest, InsertAtFilledVectorTest) EXPECT_EQ(functional_vector({ 1, 4, 2, 18, 5, 8, 3, 1, 7, 1 }), vector_under_test); } -TEST(FunctionalVectorTest, InsertingAtEmptyVectorTest) +TEST(FunctionalVectorTest, InsertingAtEmptyVector) { const functional_vector vector_under_test; EXPECT_DEATH(vector_under_test.inserting_at(15, -1), ""); @@ -784,7 +785,7 @@ TEST(FunctionalVectorTest, InsertingAtEmptyVectorTest) EXPECT_EQ(0, vector_under_test.size()); } -TEST(FunctionalVectorTest, InsertingAtFilledVectorTest) +TEST(FunctionalVectorTest, InsertingAtFilledVector) { const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_DEATH(vector_under_test.inserting_at(15, -1), ""); @@ -793,7 +794,7 @@ TEST(FunctionalVectorTest, InsertingAtFilledVectorTest) EXPECT_EQ(functional_vector({ 1, 4, 2, 5, 8, 3, 1, 7, 1 }), vector_under_test); } -TEST(FunctionalVectorTest, InsertRangeEmptyFunctionalVectorTest) +TEST(FunctionalVectorTest, InsertRangeEmptyFunctionalVector) { functional_vector vector_under_test; const functional_vector vector_to_insert({4, 7, 3, -5}); @@ -801,7 +802,7 @@ TEST(FunctionalVectorTest, InsertRangeEmptyFunctionalVectorTest) EXPECT_EQ(functional_vector({ 4, 7, 3, -5 }), vector_under_test); } -TEST(FunctionalVectorTest, InsertRangeExistingWrongInsertionIndexFunctionalVectorTest) +TEST(FunctionalVectorTest, InsertRangeExistingWrongInsertionIndexFunctionalVector) { functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); const functional_vector vector_to_insert({9, -5, 6}); @@ -809,7 +810,7 @@ TEST(FunctionalVectorTest, InsertRangeExistingWrongInsertionIndexFunctionalVecto EXPECT_DEATH(vector_under_test.insert_at(10, vector_to_insert), ""); } -TEST(FunctionalVectorTest, InsertRangeExistingFunctionalVectorTest) +TEST(FunctionalVectorTest, InsertRangeExistingFunctionalVector) { functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); const functional_vector vector_to_insert({9, -5, 6}); @@ -817,7 +818,7 @@ TEST(FunctionalVectorTest, InsertRangeExistingFunctionalVectorTest) EXPECT_EQ(functional_vector({ 1, 4, 2, 9, -5, 6, 5, 8, 3, 1, 7, 1 }), vector_under_test); } -TEST(FunctionalVectorTest, InsertRangeEmptyStdVectorTest) +TEST(FunctionalVectorTest, InsertRangeEmptyStdVector) { functional_vector vector_under_test; const std::vector vector_to_insert{4, 7, 3, -5}; @@ -825,7 +826,7 @@ TEST(FunctionalVectorTest, InsertRangeEmptyStdVectorTest) EXPECT_EQ(functional_vector({ 4, 7, 3, -5 }), vector_under_test); } -TEST(FunctionalVectorTest, InsertRangeExistingWrongInsertionIndexStdVectorTest) +TEST(FunctionalVectorTest, InsertRangeExistingWrongInsertionIndexStdVector) { functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); const std::vector vector_to_insert({9, -5, 6}); @@ -833,7 +834,7 @@ TEST(FunctionalVectorTest, InsertRangeExistingWrongInsertionIndexStdVectorTest) EXPECT_DEATH(vector_under_test.insert_at(10, vector_to_insert), ""); } -TEST(FunctionalVectorTest, InsertRangeExistingStdVectorTest) +TEST(FunctionalVectorTest, InsertRangeExistingStdVector) { functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); const std::vector vector_to_insert({9, -5, 6}); @@ -841,28 +842,28 @@ TEST(FunctionalVectorTest, InsertRangeExistingStdVectorTest) EXPECT_EQ(functional_vector({ 1, 4, 2, 9, -5, 6, 5, 8, 3, 1, 7, 1 }), vector_under_test); } -TEST(FunctionalVectorTest, InsertRangeEmptyInitializerListTest) +TEST(FunctionalVectorTest, InsertRangeEmptyInitializerList) { functional_vector vector_under_test; vector_under_test.insert_at(0, {4, 7, 3, -5}); EXPECT_EQ(functional_vector({ 4, 7, 3, -5 }), vector_under_test); } -TEST(FunctionalVectorTest, InsertRangeExistingWrongInsertionIndexInitializerListTest) +TEST(FunctionalVectorTest, InsertRangeExistingWrongInsertionIndexInitializerList) { functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_DEATH(vector_under_test.insert_at(-1, { 9, -5, 6 }), ""); EXPECT_DEATH(vector_under_test.insert_at(10, { 9, -5, 6 }), ""); } -TEST(FunctionalVectorTest, InsertRangeExistingInitializerListTest) +TEST(FunctionalVectorTest, InsertRangeExistingInitializerList) { functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); vector_under_test.insert_at(3, {9, -5, 6}); EXPECT_EQ(functional_vector({ 1, 4, 2, 9, -5, 6, 5, 8, 3, 1, 7, 1 }), vector_under_test); } -TEST(FunctionalVectorTest, InsertingRangeEmptyFunctionalVectorTest) +TEST(FunctionalVectorTest, InsertingRangeEmptyFunctionalVector) { const functional_vector vector_under_test; const functional_vector vector_to_insert({4, 7, 3, -5}); @@ -870,7 +871,7 @@ TEST(FunctionalVectorTest, InsertingRangeEmptyFunctionalVectorTest) EXPECT_EQ(functional_vector({ 4, 7, 3, -5 }), result_vector); } -TEST(FunctionalVectorTest, InsertingRangeExistingWrongInsertionIndexFunctionalVectorTest) +TEST(FunctionalVectorTest, InsertingRangeExistingWrongInsertionIndexFunctionalVector) { const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); const functional_vector vector_to_insert({9, -5, 6}); @@ -878,7 +879,7 @@ TEST(FunctionalVectorTest, InsertingRangeExistingWrongInsertionIndexFunctionalVe EXPECT_DEATH(vector_under_test.inserting_at(10, vector_to_insert), ""); } -TEST(FunctionalVectorTest, InsertingRangeExistingFunctionalVectorTest) +TEST(FunctionalVectorTest, InsertingRangeExistingFunctionalVector) { const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); const functional_vector vector_to_insert({9, -5, 6}); @@ -886,7 +887,7 @@ TEST(FunctionalVectorTest, InsertingRangeExistingFunctionalVectorTest) EXPECT_EQ(functional_vector({ 1, 4, 2, 9, -5, 6, 5, 8, 3, 1, 7, 1 }), result_vector); } -TEST(FunctionalVectorTest, InsertingRangeEmptyStdVectorTest) +TEST(FunctionalVectorTest, InsertingRangeEmptyStdVector) { const functional_vector vector_under_test; const std::vector vector_to_insert({4, 7, 3, -5}); @@ -894,7 +895,7 @@ TEST(FunctionalVectorTest, InsertingRangeEmptyStdVectorTest) EXPECT_EQ(functional_vector({ 4, 7, 3, -5 }), result_vector); } -TEST(FunctionalVectorTest, InsertingRangeExistingWrongInsertionIndexStdVectorTest) +TEST(FunctionalVectorTest, InsertingRangeExistingWrongInsertionIndexStdVector) { const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); const std::vector vector_to_insert({9, -5, 6}); @@ -902,7 +903,7 @@ TEST(FunctionalVectorTest, InsertingRangeExistingWrongInsertionIndexStdVectorTes EXPECT_DEATH(vector_under_test.inserting_at(10, vector_to_insert), ""); } -TEST(FunctionalVectorTest, InsertingRangeExistingStdVectorTest) +TEST(FunctionalVectorTest, InsertingRangeExistingStdVector) { const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); const std::vector vector_to_insert({9, -5, 6}); @@ -910,77 +911,77 @@ TEST(FunctionalVectorTest, InsertingRangeExistingStdVectorTest) EXPECT_EQ(functional_vector({ 1, 4, 2, 9, -5, 6, 5, 8, 3, 1, 7, 1 }), result_vector); } -TEST(FunctionalVectorTest, InsertingRangeEmptyInitializerListTest) +TEST(FunctionalVectorTest, InsertingRangeEmptyInitializerList) { const functional_vector vector_under_test; const auto result_vector = vector_under_test.inserting_at(0, {4, 7, 3, -5}); EXPECT_EQ(functional_vector({ 4, 7, 3, -5 }), result_vector); } -TEST(FunctionalVectorTest, InsertingRangeExistingWrongInsertionIndexInitializerListTest) +TEST(FunctionalVectorTest, InsertingRangeExistingWrongInsertionIndexInitializerList) { const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_DEATH(vector_under_test.inserting_at(-1, { 9, -5, 6 }), ""); EXPECT_DEATH(vector_under_test.inserting_at(10, { 9, -5, 6 }), ""); } -TEST(FunctionalVectorTest, InsertingRangeExistingInitializerListTest) +TEST(FunctionalVectorTest, InsertingRangeExistingInitializerList) { const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); const auto result_vector = vector_under_test.inserting_at(3, {9, -5, 6}); EXPECT_EQ(functional_vector({ 1, 4, 2, 9, -5, 6, 5, 8, 3, 1, 7, 1 }), result_vector); } -TEST(FunctionalVectorTest, RemoveIndexRangeWithInvalidRangeTest) +TEST(FunctionalVectorTest, RemoveIndexRangeWithInvalidRange) { functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); vector_under_test.remove_range(index_range::invalid); EXPECT_EQ(functional_vector({ 1, 4, 2, 5, 8, 3, 1, 7, 1 }), vector_under_test); } -TEST(FunctionalVectorTest, RemoveIndexRangeEmptyVectorTest) +TEST(FunctionalVectorTest, RemoveIndexRangeEmptyVector) { functional_vector vector_under_test; vector_under_test.remove_range(index_range::start_count(1, 12)); EXPECT_EQ(functional_vector(), vector_under_test); } -TEST(FunctionalVectorTest, RemoveIndexRangeStartCountSuccessTest) +TEST(FunctionalVectorTest, RemoveIndexRangeStartCountSuccess) { functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); vector_under_test.remove_range(index_range::start_count(2, 3)); EXPECT_EQ(functional_vector({ 1, 4, 3, 1, 7, 1 }), vector_under_test); } -TEST(FunctionalVectorTest, RemoveRangeStartEndSuccessTest) +TEST(FunctionalVectorTest, RemoveRangeStartEndSuccess) { functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); vector_under_test.remove_range(index_range::start_end(3, 6)); EXPECT_EQ(functional_vector({ 1, 4, 2, 7, 1 }), vector_under_test); } -TEST(FunctionalVectorTest, RemovingIndexRangeWithInvalidRangeTest) +TEST(FunctionalVectorTest, RemovingIndexRangeWithInvalidRange) { const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); const auto shorter_vector = vector_under_test.removing_range(index_range::invalid); EXPECT_EQ(functional_vector({ 1, 4, 2, 5, 8, 3, 1, 7, 1 }), shorter_vector); } -TEST(FunctionalVectorTest, RemovingRangeEmptyVectorTest) +TEST(FunctionalVectorTest, RemovingRangeEmptyVector) { const functional_vector vector_under_test; const auto shorter_vector = vector_under_test.removing_range(index_range::start_count(1, 12)); EXPECT_EQ(functional_vector(), shorter_vector); } -TEST(FunctionalVectorTest, RemovingIndexRangeStartCountSuccessTest) +TEST(FunctionalVectorTest, RemovingIndexRangeStartCountSuccess) { const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); const auto shorter_vector = vector_under_test.removing_range(index_range::start_count(2, 3)); EXPECT_EQ(functional_vector({ 1, 4, 3, 1, 7, 1 }), shorter_vector); } -TEST(FunctionalVectorTest, RemovingIndexRangeStartEndSuccessTest) +TEST(FunctionalVectorTest, RemovingIndexRangeStartEndSuccess) { const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); const auto shorter_vector = vector_under_test.removing_range(index_range::start_end(3, 6)); @@ -1002,27 +1003,27 @@ TEST(FunctionalVectorTest, ReplaceRangeAtWrongIndex) EXPECT_DEATH(vector_under_test.replace_range_at(5, { 1, 2, 6, 4 }), ""); } -TEST(FunctionalVectorTest, ReplaceRangeAtMoreElementsInSourceThanCapacityTest) +TEST(FunctionalVectorTest, ReplaceRangeAtMoreElementsInSourceThanCapacity) { functional_vector vector_under_test({5, -3, 4, -9}); EXPECT_DEATH(vector_under_test.replace_range_at(2, { 1, 2, 6, 4, 8, 9, -10 }), ""); } -TEST(FunctionalVectorTest, ReplaceRangeAtWithFunctionalVectorTest) +TEST(FunctionalVectorTest, ReplaceRangeAtWithFunctionalVector) { functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); vector_under_test.replace_range_at(4, functional_vector({9, -10, 8})); EXPECT_EQ(functional_vector({ 1, 4, 2, 5, 9, -10, 8, 7, 1 }), vector_under_test); } -TEST(FunctionalVectorTest, ReplaceRangeAtWithStdVectorTest) +TEST(FunctionalVectorTest, ReplaceRangeAtWithStdVector) { functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); vector_under_test.replace_range_at(4, std::vector({9, -10, 8})); EXPECT_EQ(functional_vector({ 1, 4, 2, 5, 9, -10, 8, 7, 1 }), vector_under_test); } -TEST(FunctionalVectorTest, ReplaceRangeAtWithInitializerListTest) +TEST(FunctionalVectorTest, ReplaceRangeAtWithInitializerList) { functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); vector_under_test.replace_range_at(4, std::initializer_list({9, -10, 8})); @@ -1044,47 +1045,47 @@ TEST(FunctionalVectorTest, ReplacingRangeAtWrongIndex) EXPECT_DEATH(vector_under_test.replacing_range_at(5, { 1, 2, 6, 4 }), ""); } -TEST(FunctionalVectorTest, ReplacingRangeAtMoreElementsInSourceThanCapacityTest) +TEST(FunctionalVectorTest, ReplacingRangeAtMoreElementsInSourceThanCapacity) { const functional_vector vector_under_test({5, -3, 4, -9}); EXPECT_DEATH(vector_under_test.replacing_range_at(2, { 1, 2, 6, 4, 8, 9, -10 }), ""); } -TEST(FunctionalVectorTest, ReplacingRangeAtWithFunctionalVectorTest) +TEST(FunctionalVectorTest, ReplacingRangeAtWithFunctionalVector) { const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); const auto replaced_vector = vector_under_test.replacing_range_at(4, functional_vector({9, -10, 8})); EXPECT_EQ(functional_vector({ 1, 4, 2, 5, 9, -10, 8, 7, 1 }), replaced_vector); } -TEST(FunctionalVectorTest, ReplacingRangeAtWithStdVectorTest) +TEST(FunctionalVectorTest, ReplacingRangeAtWithStdVector) { const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); const auto replaced_vector = vector_under_test.replacing_range_at(4, std::vector({9, -10, 8})); EXPECT_EQ(functional_vector({ 1, 4, 2, 5, 9, -10, 8, 7, 1 }), replaced_vector); } -TEST(FunctionalVectorTest, ReplacingRangeAtWithInitializerListTest) +TEST(FunctionalVectorTest, ReplacingRangeAtWithInitializerList) { const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); const auto replaced_vector = vector_under_test.replacing_range_at(4, std::initializer_list({9, -10, 8})); EXPECT_EQ(functional_vector({ 1, 4, 2, 5, 9, -10, 8, 7, 1 }), replaced_vector); } -TEST(FunctionalVectorTest, FillTest) +TEST(FunctionalVectorTest, Fill) { functional_vector vector_under_test({1, 3, -6, 4, -9}); vector_under_test.fill(7); EXPECT_EQ(functional_vector({ 7, 7, 7, 7, 7 }), vector_under_test); } -TEST(FunctionalVectorTest, RepeatingConstructorTest) +TEST(FunctionalVectorTest, RepeatingConstructor) { const functional_vector vector_under_test(3, "John"); EXPECT_EQ(functional_vector({ "John", "John", "John" }), vector_under_test); } -TEST(FunctionalVectorTest, EqualityOperatorEmptyVectorsTest) +TEST(FunctionalVectorTest, EqualityOperatorEmptyVectors) { const functional_vector vec1; const functional_vector vec2; @@ -1092,7 +1093,7 @@ TEST(FunctionalVectorTest, EqualityOperatorEmptyVectorsTest) EXPECT_FALSE(vec1 != vec2); } -TEST(FunctionalVectorTest, EqualityOperatorUnequalSizesTest) +TEST(FunctionalVectorTest, EqualityOperatorUnequalSizes) { const functional_vector vec1({1, 2, 3}); const functional_vector vec2({1, 2, 3, 4}); @@ -1100,7 +1101,7 @@ TEST(FunctionalVectorTest, EqualityOperatorUnequalSizesTest) EXPECT_FALSE(vec1 == vec2); } -TEST(FunctionalVectorTest, EqualityOperatorEqualSizesDifferentElementsTest) +TEST(FunctionalVectorTest, EqualityOperatorEqualSizesDifferentElements) { const functional_vector vec1({1, 2, 3}); const functional_vector vec2({1, 2, 4}); @@ -1108,7 +1109,7 @@ TEST(FunctionalVectorTest, EqualityOperatorEqualSizesDifferentElementsTest) EXPECT_FALSE(vec1 == vec2); } -TEST(FunctionalVectorTest, EqualityOperatorEqualVectorsTest) +TEST(FunctionalVectorTest, EqualityOperatorEqualVectors) { const functional_vector vec1({1, 2, 3}); const functional_vector vec2({1, 2, 3}); @@ -1116,7 +1117,7 @@ TEST(FunctionalVectorTest, EqualityOperatorEqualVectorsTest) EXPECT_FALSE(vec1 != vec2); } -TEST(FunctionalVectorTest, ClearEmptyVectorTest) +TEST(FunctionalVectorTest, ClearEmptyVector) { functional_vector vector_under_test; EXPECT_TRUE(vector_under_test.is_empty()); @@ -1125,7 +1126,7 @@ TEST(FunctionalVectorTest, ClearEmptyVectorTest) EXPECT_TRUE(vector_under_test.is_empty()); } -TEST(FunctionalVectorTest, ClearFilledVectorTest) +TEST(FunctionalVectorTest, ClearFilledVector) { functional_vector vector_under_test({5, -3, 4, -9}); EXPECT_FALSE(vector_under_test.is_empty()); @@ -1134,7 +1135,7 @@ TEST(FunctionalVectorTest, ClearFilledVectorTest) EXPECT_TRUE(vector_under_test.is_empty()); } -TEST(FunctionalVectorTest, CapacityReserveClearTest) +TEST(FunctionalVectorTest, CapacityReserveClear) { functional_vector vector_under_test; EXPECT_EQ(0, vector_under_test.capacity()); @@ -1153,7 +1154,7 @@ TEST(FunctionalVectorTest, CapacityReserveClearTest) EXPECT_EQ(0, vector_under_test.size()); } -TEST(FunctionalVectorTest, ResizeEmptyVectorTest) +TEST(FunctionalVectorTest, ResizeEmptyVector) { functional_vector vector_under_test; vector_under_test.resize(5); @@ -1162,7 +1163,7 @@ TEST(FunctionalVectorTest, ResizeEmptyVectorTest) EXPECT_EQ(5, vector_under_test.size()); } -TEST(FunctionalVectorTest, ResizeSmallerThanCurrentSizeTest) +TEST(FunctionalVectorTest, ResizeSmallerThanCurrentSize) { functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_EQ(9, vector_under_test.capacity()); @@ -1174,13 +1175,13 @@ TEST(FunctionalVectorTest, ResizeSmallerThanCurrentSizeTest) EXPECT_EQ(5, vector_under_test.size()); } -TEST(FunctionalVectorTest, AllOfFalseTest) +TEST(FunctionalVectorTest, AllOfFalse) { functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_FALSE(vector_under_test.all_of([](const int& number) { return number > 5; })); } -TEST(FunctionalVectorTest, AllOfTrueTest) +TEST(FunctionalVectorTest, AllOfTrue) { functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); vector_under_test.all_of([](const int& number) { @@ -1190,13 +1191,13 @@ TEST(FunctionalVectorTest, AllOfTrueTest) } #ifdef PARALLEL_ALGORITHM_AVAILABLE -TEST(FunctionalVectorTest, AllOfParallelFalseTest) +TEST(FunctionalVectorTest, AllOfParallelFalse) { functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_FALSE(vector_under_test.all_of_parallel([](const int& number) { return number > 5; })); } -TEST(FunctionalVectorTest, AllOfParallelTrueTest) +TEST(FunctionalVectorTest, AllOfParallelTrue) { functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); vector_under_test.all_of([](const int& number) { @@ -1206,58 +1207,58 @@ TEST(FunctionalVectorTest, AllOfParallelTrueTest) } #endif -TEST(FunctionalVectorTest, AnyOfFalseTest) +TEST(FunctionalVectorTest, AnyOfFalse) { functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_FALSE(vector_under_test.any_of([](const int& number) { return number > 20; })); } -TEST(FunctionalVectorTest, AnyOfTrueTest) +TEST(FunctionalVectorTest, AnyOfTrue) { functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_TRUE(vector_under_test.any_of([](const int& number) { return number >= 7; })); } #ifdef PARALLEL_ALGORITHM_AVAILABLE -TEST(FunctionalVectorTest, AnyOfParallelFalseTest) +TEST(FunctionalVectorTest, AnyOfParallelFalse) { functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_FALSE(vector_under_test.any_of_parallel([](const int& number) { return number > 20; })); } -TEST(FunctionalVectorTest, AnyOfParallelTrueTest) +TEST(FunctionalVectorTest, AnyOfParallelTrue) { functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_TRUE(vector_under_test.any_of_parallel([](const int& number) { return number >= 7; })); } #endif -TEST(FunctionalVectorTest, NoneOfFalseTest) +TEST(FunctionalVectorTest, NoneOfFalse) { functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_FALSE(vector_under_test.none_of([](const int& number) { return number > 7; })); } -TEST(FunctionalVectorTest, NoneOfTrueTest) +TEST(FunctionalVectorTest, NoneOfTrue) { functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_TRUE(vector_under_test.none_of([](const int& number) { return number < -2; })); } #ifdef PARALLEL_ALGORITHM_AVAILABLE -TEST(FunctionalVectorTest, NoneOfParallelFalseTest) +TEST(FunctionalVectorTest, NoneOfParallelFalse) { functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_FALSE(vector_under_test.none_of_parallel([](const int& number) { return number > 7; })); } -TEST(FunctionalVectorTest, NoneOfParallelTrueTest) +TEST(FunctionalVectorTest, NoneOfParallelTrue) { functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_TRUE(vector_under_test.none_of_parallel([](const int& number) { return number < -2; })); } -TEST(FunctionalVectorTest, ForEachParallelTest) +TEST(FunctionalVectorTest, ForEachParallel) { functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_EQ(9, vector_under_test.size()); @@ -1266,3 +1267,10 @@ TEST(FunctionalVectorTest, ForEachParallelTest) EXPECT_EQ(9, counter); } #endif + +TEST(FunctionalVectorTest, Distinct) +{ + const functional_vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); + const auto& unique_numbers = numbers.distinct(); + EXPECT_EQ(functional_set({1, 2, 3, 4, 5, 7, 8}), unique_numbers); +} From 608b4e0f8281c6cb79683c193586af76b7a740b4 Mon Sep 17 00:00:00 2001 From: jkaliak Date: Tue, 5 Jul 2022 22:02:42 +0200 Subject: [PATCH 11/44] renamed difference_with --- include/functional_set.h | 6 +++--- tests/functional_set_test.cc | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/functional_set.h b/include/functional_set.h index ba2f5c5..9210154 100644 --- a/include/functional_set.h +++ b/include/functional_set.h @@ -73,7 +73,7 @@ class functional_set // // outcome: // diff -> functional_set({1, 3, 8}) - functional_set difference(const functional_set& other) const { + functional_set difference_with(const functional_set& other) const { std::set diff; std::set_difference(cbegin(), cend(), @@ -83,8 +83,8 @@ class functional_set return functional_set(diff); } - functional_set difference(const std::set& other) const { - return difference(functional_set(other)); + functional_set difference_with(const std::set& other) const { + return difference_with(functional_set(other)); } // Returns the set of elements which belong either to the current or the other set. diff --git a/tests/functional_set_test.cc b/tests/functional_set_test.cc index d2a5a19..10cb264 100644 --- a/tests/functional_set_test.cc +++ b/tests/functional_set_test.cc @@ -90,7 +90,7 @@ TEST(FunctionalSetTest, Difference) { const functional_set set1(std::set({1, 2, 3, 5, 7, 8, 10})); const functional_set set2(std::set({2, 5, 7, 10, 15, 17})); - const auto& diff = set1.difference(set2); + const auto& diff = set1.difference_with(set2); EXPECT_EQ(functional_set({1, 3, 8}), diff); } @@ -98,7 +98,7 @@ TEST(FunctionalSetTest, DifferenceStdSet) { const functional_set set1(std::set({1, 2, 3, 5, 7, 8, 10})); const std::set set2({2, 5, 7, 10, 15, 17}); - const auto& diff = set1.difference(set2); + const auto& diff = set1.difference_with(set2); EXPECT_EQ(functional_set({1, 3, 8}), diff); } From b6636f2e05f2cd5c26078f0c0e04a2ad722ff97c Mon Sep 17 00:00:00 2001 From: jkaliak Date: Tue, 5 Jul 2022 22:23:12 +0200 Subject: [PATCH 12/44] set min and max --- include/functional_set.h | 43 ++++++++++++++++++++++++++++++++++-- tests/functional_set_test.cc | 30 +++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 2 deletions(-) diff --git a/include/functional_set.h b/include/functional_set.h index 9210154..6da1c0a 100644 --- a/include/functional_set.h +++ b/include/functional_set.h @@ -23,6 +23,7 @@ #pragma once #include #include +#include "optional.h" template class functional_vector; @@ -137,8 +138,46 @@ class functional_set return intersect_with(functional_set(other)); } - // min - // max + // Returns the minimum key in the set, if it's not empty. + // + // example: + // const functional_set numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); + // auto minimum = numbers.min(); + // + // // an empty's set minimum value + // functional_set().min().has_value() // false + // + // outcome: + // minimum.has_value() -> true + // minimum.value() -> 1 + optional_t min() const { + const auto& it = std::min_element(cbegin(), cend()); + if (it != cend()) { + return *it; + } + return optional_t(); + } + + // Returns the maximum key in the set, if it's not empty. + // + // example: + // const functional_set numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); + // auto maximum = numbers.max(); + // + // // an empty's set maximum value + // functional_set().maxn().has_value() // false + // + // outcome: + // maximum.has_value() -> true + // maximum.value() -> 8 + optional_t max() const { + const auto& it = std::max_element(cbegin(), cend()); + if (it != cend()) { + return *it; + } + return optional_t(); + } + // map algorithm // map parallel algorithm // all_of diff --git a/tests/functional_set_test.cc b/tests/functional_set_test.cc index 10cb264..be6b7ab 100644 --- a/tests/functional_set_test.cc +++ b/tests/functional_set_test.cc @@ -134,6 +134,36 @@ TEST(FunctionalSetTest, IntersectionStdSet) EXPECT_EQ(functional_set({2, 5, 7, 10}), intersection); } +TEST(FunctionalSetTest, Min) +{ + const functional_set numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); + auto minimum = numbers.min(); + EXPECT_TRUE(minimum.has_value()); + EXPECT_EQ(1, minimum.value()); +} + +TEST(FunctionalSetTest, MinEmptySet) +{ + const functional_set numbers; + auto minimum = numbers.min(); + EXPECT_FALSE(minimum.has_value()); +} + +TEST(FunctionalSetTest, Max) +{ + const functional_set numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); + auto maximum = numbers.max(); + EXPECT_TRUE(maximum.has_value()); + EXPECT_EQ(8, maximum.value()); +} + +TEST(FunctionalSetTest, MaxEmptySet) +{ + const functional_set numbers; + auto maximum = numbers.max(); + EXPECT_FALSE(maximum.has_value()); +} + TEST(FunctionalSetTest, EqualityOperator) { const functional_set set1(std::set({1, 2, 3})); From 99592f0d0553109e55e9e139ef69184921b8f712 Mon Sep 17 00:00:00 2001 From: jkaliak Date: Tue, 5 Jul 2022 22:48:01 +0200 Subject: [PATCH 13/44] Fixed compiler error for C++17 (std::advance) --- include/functional_set.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/functional_set.h b/include/functional_set.h index 6da1c0a..b1b71a3 100644 --- a/include/functional_set.h +++ b/include/functional_set.h @@ -265,7 +265,8 @@ class functional_set { assert_smaller_size(index); #ifdef CPP17_AVAILABLE - auto it = std::advance(begin(), index); + auto it = cbegin(); + std::advance(it, index); return *it; #else auto count = 0; From e72fd52acaeae1d6f70d90f162753604b7971aeb Mon Sep 17 00:00:00 2001 From: jkaliak Date: Thu, 7 Jul 2022 23:28:14 +0200 Subject: [PATCH 14/44] vector equality for custom types --- include/functional_vector.h | 2 +- tests/functional_set_test.cc | 1 + tests/functional_vector_test.cc | 55 +++++++++++++++++++++++++++++++++ tests/test_types.h | 4 +++ 4 files changed, 61 insertions(+), 1 deletion(-) diff --git a/include/functional_vector.h b/include/functional_vector.h index abd620c..25ae947 100644 --- a/include/functional_vector.h +++ b/include/functional_vector.h @@ -1476,7 +1476,7 @@ class functional_vector } for (auto i = 0; i < size(); ++i) { - if ((*this)[i] != rhs[i]) { + if (!((*this)[i] == rhs[i])) { return false; } } diff --git a/tests/functional_set_test.cc b/tests/functional_set_test.cc index be6b7ab..d1c0e0a 100644 --- a/tests/functional_set_test.cc +++ b/tests/functional_set_test.cc @@ -24,6 +24,7 @@ #include "warnings.h" #include "functional_set.h" #include "functional_vector.h" +#include "test_types.h"" template void debug(functional_set& set) diff --git a/tests/functional_vector_test.cc b/tests/functional_vector_test.cc index 92baf0f..100bb06 100644 --- a/tests/functional_vector_test.cc +++ b/tests/functional_vector_test.cc @@ -1117,6 +1117,61 @@ TEST(FunctionalVectorTest, EqualityOperatorEqualVectors) EXPECT_FALSE(vec1 != vec2); } +TEST(FunctionalVectorTest, EqualityOperatorCustomTypeEqualVectors) +{ + const functional_vector vec1({ + person(15, "Jake"), + person(18, "Jannet"), + person(25, "Kate") + }); + + const functional_vector vec2({ + person(15, "Jake"), + person(18, "Jannet"), + person(25, "Kate") + }); + + EXPECT_TRUE(vec1 == vec2); + EXPECT_FALSE(vec1 != vec2); +} + +TEST(FunctionalVectorTest, EqualityOperatorCustomTypeUnequalSizes) +{ + const functional_vector vec1({ + person(15, "Jake"), + person(18, "Jannet"), + person(25, "Kate") + }); + + const functional_vector vec2({ + person(15, "Jake"), + person(18, "Jannet"), + person(25, "Kate"), + person(50, "Barbara") + }); + + EXPECT_FALSE(vec1 == vec2); + EXPECT_TRUE(vec1 != vec2); +} + +TEST(FunctionalVectorTest, EqualityOperatorCustomTypeUnequalVectors) +{ + const functional_vector vec1({ + person(15, "Jake"), + person(18, "Jannet"), + person(25, "Kate") + }); + + const functional_vector vec2({ + person(15, "Jake"), + person(53, "Bob"), + person(35, "Suzan") + }); + + EXPECT_FALSE(vec1 == vec2); + EXPECT_TRUE(vec1 != vec2); +} + TEST(FunctionalVectorTest, ClearEmptyVector) { functional_vector vector_under_test; diff --git a/tests/test_types.h b/tests/test_types.h index 82e5fb3..f593b34 100644 --- a/tests/test_types.h +++ b/tests/test_types.h @@ -52,4 +52,8 @@ struct person int age; std::string name; + + bool operator == (const person& other) const { + return age == other.age && name == other.name; + } }; From 3d7213dc5e57fa25bab44589c60605548e3f1241 Mon Sep 17 00:00:00 2001 From: jkaliak Date: Thu, 7 Jul 2022 23:43:37 +0200 Subject: [PATCH 15/44] Set equality and distinct from vector with custom type comparator --- include/functional_set.h | 56 ++++++++++++++++----------------- include/functional_vector.h | 7 +++-- tests/functional_set_test.cc | 18 +++++++++++ tests/functional_vector_test.cc | 23 ++++++++++++++ tests/test_types.h | 13 ++++++++ 5 files changed, 86 insertions(+), 31 deletions(-) diff --git a/include/functional_set.h b/include/functional_set.h index b1b71a3..aea7116 100644 --- a/include/functional_set.h +++ b/include/functional_set.h @@ -34,7 +34,7 @@ class functional_vector; // // Member functions can be mutating (eg. my_set.insert()) or // non-mutating (eg. my_vector.inserting()) enforcing thread safety if needed -template +template > class functional_set { public: @@ -43,22 +43,22 @@ class functional_set { } - explicit functional_set(const std::set& set) + explicit functional_set(const std::set& set) : backing_set_(set) { } - explicit functional_set(const std::vector& vector) + explicit functional_set(const std::vector& vector) : backing_set_(vector.begin(), vector.end()) { } - explicit functional_set(const functional_vector& vector) + explicit functional_set(const functional_vector& vector) : backing_set_(vector.cbegin(), vector.cend()) { } - explicit functional_set(const std::initializer_list& list) + explicit functional_set(const std::initializer_list& list) : backing_set_(list.begin(), list.end()) { } @@ -74,8 +74,8 @@ class functional_set // // outcome: // diff -> functional_set({1, 3, 8}) - functional_set difference_with(const functional_set& other) const { - std::set diff; + functional_set difference_with(const functional_set& other) const { + std::set diff; std::set_difference(cbegin(), cend(), other.cbegin(), @@ -84,7 +84,7 @@ class functional_set return functional_set(diff); } - functional_set difference_with(const std::set& other) const { + functional_set difference_with(const std::set& other) const { return difference_with(functional_set(other)); } @@ -99,8 +99,8 @@ class functional_set // // outcome: // combined -> functional_set({1, 2, 3, 5, 7, 8, 10, 15, 17}) - functional_set union_with(const functional_set& other) const { - std::set combined; + functional_set union_with(const functional_set& other) const { + std::set combined; std::set_union(cbegin(), cend(), other.cbegin(), @@ -109,7 +109,7 @@ class functional_set return functional_set(combined); } - functional_set union_with(const std::set& other) const { + functional_set union_with(const std::set& other) const { return union_with(functional_set(other)); } @@ -124,8 +124,8 @@ class functional_set // // outcome: // combined -> functional_set({2, 5, 7, 10}) - functional_set intersect_with(const functional_set& other) const { - std::set intersection; + functional_set intersect_with(const functional_set& other) const { + std::set intersection; std::set_intersection(cbegin(), cend(), other.cbegin(), @@ -134,7 +134,7 @@ class functional_set return functional_set(intersection); } - functional_set intersect_with(const std::set& other) const { + functional_set intersect_with(const std::set& other) const { return intersect_with(functional_set(other)); } @@ -150,12 +150,12 @@ class functional_set // outcome: // minimum.has_value() -> true // minimum.value() -> 1 - optional_t min() const { + optional_t min() const { const auto& it = std::min_element(cbegin(), cend()); if (it != cend()) { return *it; } - return optional_t(); + return optional_t(); } // Returns the maximum key in the set, if it's not empty. @@ -170,12 +170,12 @@ class functional_set // outcome: // maximum.has_value() -> true // maximum.value() -> 8 - optional_t max() const { + optional_t max() const { const auto& it = std::max_element(cbegin(), cend()); if (it != cend()) { return *it; } - return optional_t(); + return optional_t(); } // map algorithm @@ -216,25 +216,25 @@ class functional_set // reserve // Returns the begin iterator, useful for other standard library algorithms - [[nodiscard]] typename std::set::iterator begin() + [[nodiscard]] typename std::set::iterator begin() { return backing_set_.begin(); } // Returns the const begin iterator, useful for other standard library algorithms - [[nodiscard]] typename std::set::const_iterator cbegin() const + [[nodiscard]] typename std::set::const_iterator cbegin() const { return backing_set_.begin(); } // Returns the end iterator, useful for other standard library algorithms - [[nodiscard]] typename std::set::iterator end() + [[nodiscard]] typename std::set::iterator end() { return backing_set_.end(); } // Returns the const end iterator, useful for other standard library algorithms - [[nodiscard]] typename std::set::const_iterator cend() const + [[nodiscard]] typename std::set::const_iterator cend() const { return backing_set_.end(); } @@ -242,7 +242,7 @@ class functional_set // Returns the given key in the current set, allowing subscripting. // Bounds checking (assert) is enabled for debug builds. // Performance is O(n), so be careful for performance critical code sections. - T operator[](int index) + TKey operator[](int index) { assert_smaller_size(index); #ifdef CPP17_AVAILABLE @@ -261,7 +261,7 @@ class functional_set // Returns the given key in the current constant set, allowing subscripting. // Bounds checking (assert) is enabled for debug builds. // Performance is O(n), so be careful for performance critical code sections. - T operator[](int index) const + TKey operator[](int index) const { assert_smaller_size(index); #ifdef CPP17_AVAILABLE @@ -279,7 +279,7 @@ class functional_set } // Returns true if both instances have equal sizes and the corresponding elements (keys) are equal - bool operator ==(const functional_set& rhs) const + bool operator ==(const functional_set& rhs) const { #ifdef CPP17_AVAILABLE return std::equal(cbegin(), @@ -294,7 +294,7 @@ class functional_set auto it1 = cbegin(); auto it2 = rhs.cbegin(); while (it1 != cend() && it2 != rhs.cend()) { - if (*it1 != *it2) { + if (!(*it1 == *it2)) { return false; } it1++; @@ -306,13 +306,13 @@ class functional_set } // Returns false if either the sizes are not equal or at least one corresponding element (key) is not equal - bool operator !=(const functional_set& rhs) const + bool operator !=(const functional_set& rhs) const { return !((*this) == rhs); } private: - std::set backing_set_; + std::set backing_set_; void assert_smaller_size(int index) const { diff --git a/include/functional_vector.h b/include/functional_vector.h index 25ae947..c40a819 100644 --- a/include/functional_vector.h +++ b/include/functional_vector.h @@ -30,7 +30,7 @@ #include #endif -template +template class functional_set; // A lightweight wrapper around std::vector, enabling fluent and functional @@ -1442,8 +1442,9 @@ class functional_vector // // outcome: // unique_numbers -> functional_set({1, 2, 3, 4, 5, 7, 8}) - functional_set distinct() const { - return functional_set(*this); + template > + functional_set distinct() const { + return functional_set(*this); } // Returns a reference to the element in the given index, allowing subscripting and value editing. diff --git a/tests/functional_set_test.cc b/tests/functional_set_test.cc index d1c0e0a..16ea6e5 100644 --- a/tests/functional_set_test.cc +++ b/tests/functional_set_test.cc @@ -180,3 +180,21 @@ TEST(FunctionalSetTest, InequalityOperator) EXPECT_FALSE(set1 == set2); EXPECT_TRUE(set1 != set2); } + +TEST(FunctionalSetTest, EqualityOperatorCustomType) +{ + const functional_set vec1({ + person(15, "Jake"), + person(18, "Jannet"), + person(25, "Kate") + }); + + const functional_set vec2({ + person(15, "Jake"), + person(18, "Jannet"), + person(25, "Kate") + }); + + EXPECT_TRUE(vec1 == vec2); + EXPECT_FALSE(vec1 != vec2); +} diff --git a/tests/functional_vector_test.cc b/tests/functional_vector_test.cc index 100bb06..8747854 100644 --- a/tests/functional_vector_test.cc +++ b/tests/functional_vector_test.cc @@ -1329,3 +1329,26 @@ TEST(FunctionalVectorTest, Distinct) const auto& unique_numbers = numbers.distinct(); EXPECT_EQ(functional_set({1, 2, 3, 4, 5, 7, 8}), unique_numbers); } + +TEST(FunctionalVectorTest, DistinctCustomType) +{ + const functional_vector persons({ + person(15, "Jake"), + person(15, "Jake"), + person(18, "Jannet"), + person(25, "Kate"), + person(25, "Kate"), + person(62, "Bob") + }); + + const auto& unique_persons = persons.distinct(); + + const functional_set expected({ + person(15, "Jake"), + person(18, "Jannet"), + person(25, "Kate"), + person(62, "Bob") + }); + + EXPECT_EQ(expected, unique_persons); +} diff --git a/tests/test_types.h b/tests/test_types.h index f593b34..323f69f 100644 --- a/tests/test_types.h +++ b/tests/test_types.h @@ -53,7 +53,20 @@ struct person int age; std::string name; + std::size_t hash() const { + std::size_t h1 = std::hash{}(name); + std::size_t h2 = std::hash{}(age); + return h1 ^ (h2 << 1); + } + + bool operator == (const person& other) const { return age == other.age && name == other.name; } }; + +struct person_comparator { + bool operator() (const person& a, const person& b) const { + return a.hash() < b.hash(); + } +}; From f1bda3c21de5a959044da7aa7eb6ddfed1a34754 Mon Sep 17 00:00:00 2001 From: jkaliak Date: Fri, 8 Jul 2022 00:00:06 +0200 Subject: [PATCH 16/44] difference, intersect and union with custom types --- include/functional_set.h | 18 +++--- tests/functional_set_test.cc | 104 +++++++++++++++++++++++++++++++++++ tests/test_types.h | 7 ++- 3 files changed, 118 insertions(+), 11 deletions(-) diff --git a/include/functional_set.h b/include/functional_set.h index aea7116..2c33c8e 100644 --- a/include/functional_set.h +++ b/include/functional_set.h @@ -74,8 +74,8 @@ class functional_set // // outcome: // diff -> functional_set({1, 3, 8}) - functional_set difference_with(const functional_set& other) const { - std::set diff; + functional_set difference_with(const functional_set& other) const { + std::set diff; std::set_difference(cbegin(), cend(), other.cbegin(), @@ -84,7 +84,7 @@ class functional_set return functional_set(diff); } - functional_set difference_with(const std::set& other) const { + functional_set difference_with(const std::set& other) const { return difference_with(functional_set(other)); } @@ -99,8 +99,8 @@ class functional_set // // outcome: // combined -> functional_set({1, 2, 3, 5, 7, 8, 10, 15, 17}) - functional_set union_with(const functional_set& other) const { - std::set combined; + functional_set union_with(const functional_set& other) const { + std::set combined; std::set_union(cbegin(), cend(), other.cbegin(), @@ -109,7 +109,7 @@ class functional_set return functional_set(combined); } - functional_set union_with(const std::set& other) const { + functional_set union_with(const std::set& other) const { return union_with(functional_set(other)); } @@ -124,8 +124,8 @@ class functional_set // // outcome: // combined -> functional_set({2, 5, 7, 10}) - functional_set intersect_with(const functional_set& other) const { - std::set intersection; + functional_set intersect_with(const functional_set& other) const { + std::set intersection; std::set_intersection(cbegin(), cend(), other.cbegin(), @@ -134,7 +134,7 @@ class functional_set return functional_set(intersection); } - functional_set intersect_with(const std::set& other) const { + functional_set intersect_with(const std::set& other) const { return intersect_with(functional_set(other)); } diff --git a/tests/functional_set_test.cc b/tests/functional_set_test.cc index 16ea6e5..d2b456b 100644 --- a/tests/functional_set_test.cc +++ b/tests/functional_set_test.cc @@ -103,6 +103,40 @@ TEST(FunctionalSetTest, DifferenceStdSet) EXPECT_EQ(functional_set({1, 3, 8}), diff); } +TEST(FunctionalSetTest, DifferenceFunctionalSet) +{ + const functional_set set1({1, 2, 3, 5, 7, 8, 10}); + const functional_set set2({2, 5, 7, 10, 15, 17}); + const auto& diff = set1.difference_with(set2); + EXPECT_EQ(functional_set({1, 3, 8}), diff); +} + +TEST(FunctionalSetTest, DifferenceFunctionalSetCustomType) +{ + const functional_set set1({ + person(51, "George"), + person(81, "Jackie"), + person(15, "Jake"), + person(18, "Jannet"), + person(25, "Kate") + }); + + const functional_set set2({ + person(51, "George"), + person(81, "Jackie"), + }); + + const auto& diff = set1.difference_with(set2); + + const functional_set expected({ + person(15, "Jake"), + person(18, "Jannet"), + person(25, "Kate") + }); + + EXPECT_EQ(expected, diff); +} + TEST(FunctionalSetTest, Union) { const functional_set set1(std::set({1, 2, 3, 5, 7, 8, 10})); @@ -119,6 +153,40 @@ TEST(FunctionalSetTest, UnionStdSet) EXPECT_EQ(functional_set({1, 2, 3, 5, 7, 8, 10, 15, 17}), combined); } +TEST(FunctionalSetTest, UnionFunctionalSet) +{ + const functional_set set1({1, 2, 3, 5, 7, 8, 10}); + const functional_set set2({2, 5, 7, 10, 15, 17}); + const auto& combined = set1.union_with(set2); + EXPECT_EQ(functional_set({1, 2, 3, 5, 7, 8, 10, 15, 17}), combined); +} + +TEST(FunctionalSetTest, UnionFunctionalSetCustomType) +{ + const functional_set set1({ + person(15, "Jake"), + person(18, "Jannet"), + person(25, "Kate") + }); + + const functional_set set2({ + person(51, "George"), + person(81, "Jackie"), + }); + + const auto& combined = set1.union_with(set2); + + const functional_set expected({ + person(15, "Jake"), + person(18, "Jannet"), + person(25, "Kate"), + person(51, "George"), + person(81, "Jackie"), + }); + + EXPECT_EQ(expected, combined); +} + TEST(FunctionalSetTest, Intersection) { const functional_set set1(std::set({1, 2, 3, 5, 7, 8, 10})); @@ -135,6 +203,42 @@ TEST(FunctionalSetTest, IntersectionStdSet) EXPECT_EQ(functional_set({2, 5, 7, 10}), intersection); } +TEST(FunctionalSetTest, IntersectionFunctionalSet) +{ + const functional_set set1({1, 2, 3, 5, 7, 8, 10}); + const functional_set set2({2, 5, 7, 10, 15, 17}); + const auto& intersection = set1.intersect_with(set2); + EXPECT_EQ(functional_set({2, 5, 7, 10}), intersection); +} + +TEST(FunctionalSetTest, IntersectionFunctionalSetCustomType) +{ + const functional_set set1({ + person(15, "Jake"), + person(18, "Jannet"), + person(25, "Kate"), + person(51, "George"), + person(81, "Jackie"), + }); + + const functional_set set2({ + person(39, "Robert"), + person(18, "Jannet"), + person(25, "Kate"), + person(52, "Anna"), + person(63, "Simon"), + }); + + const auto& intersection = set1.intersect_with(set2); + + const functional_set expected({ + person(18, "Jannet"), + person(25, "Kate"), + }); + + EXPECT_EQ(expected, intersection); +} + TEST(FunctionalSetTest, Min) { const functional_set numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); diff --git a/tests/test_types.h b/tests/test_types.h index 323f69f..2b7ea4d 100644 --- a/tests/test_types.h +++ b/tests/test_types.h @@ -58,15 +58,18 @@ struct person std::size_t h2 = std::hash{}(age); return h1 ^ (h2 << 1); } - bool operator == (const person& other) const { return age == other.age && name == other.name; } + + bool operator< (const person& other) const { + return hash() < other.hash(); + } }; struct person_comparator { bool operator() (const person& a, const person& b) const { - return a.hash() < b.hash(); + return a < b; } }; From 4c6d28a125b11357d273893fea88dcd0b07fce85 Mon Sep 17 00:00:00 2001 From: jkaliak Date: Mon, 11 Jul 2022 21:08:37 +0200 Subject: [PATCH 17/44] Min/Max CustomType tests --- tests/functional_set_test.cc | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/functional_set_test.cc b/tests/functional_set_test.cc index d2b456b..dabe1c3 100644 --- a/tests/functional_set_test.cc +++ b/tests/functional_set_test.cc @@ -247,6 +247,18 @@ TEST(FunctionalSetTest, Min) EXPECT_EQ(1, minimum.value()); } +TEST(FunctionalSetTest, MinCustomType) +{ + const functional_set persons({ + person(15, "Jake"), + person(18, "Jannet"), + person(25, "Kate"), + person(62, "Bob") + }); + auto minimum = persons.min(); + EXPECT_EQ(person(18, "Jannet"), minimum.value()); +} + TEST(FunctionalSetTest, MinEmptySet) { const functional_set numbers; @@ -262,6 +274,18 @@ TEST(FunctionalSetTest, Max) EXPECT_EQ(8, maximum.value()); } +TEST(FunctionalSetTest, MaxCustomType) +{ + const functional_set persons({ + person(15, "Jake"), + person(18, "Jannet"), + person(25, "Kate"), + person(62, "Bob") + }); + auto maximum = persons.max(); + EXPECT_EQ(person(25, "Kate"), maximum.value()); +} + TEST(FunctionalSetTest, MaxEmptySet) { const functional_set numbers; From 04fab0fbe25171401ca1821a1579ed1d6cdfb87c Mon Sep 17 00:00:00 2001 From: jkaliak Date: Mon, 11 Jul 2022 21:46:50 +0200 Subject: [PATCH 18/44] set map algorithm --- include/functional_set.h | 90 ++++++++++++++++++++++++------------ include/functional_vector.h | 44 +++++++++--------- tests/functional_set_test.cc | 12 +++++ tests/test_types.h | 14 ++++++ 4 files changed, 108 insertions(+), 52 deletions(-) diff --git a/include/functional_set.h b/include/functional_set.h index 2c33c8e..c0a8cc8 100644 --- a/include/functional_set.h +++ b/include/functional_set.h @@ -54,7 +54,7 @@ class functional_set } explicit functional_set(const functional_vector& vector) - : backing_set_(vector.cbegin(), vector.cend()) + : backing_set_(vector.begin(), vector.end()) { } @@ -76,10 +76,10 @@ class functional_set // diff -> functional_set({1, 3, 8}) functional_set difference_with(const functional_set& other) const { std::set diff; - std::set_difference(cbegin(), - cend(), - other.cbegin(), - other.cend(), + std::set_difference(begin(), + end(), + other.begin(), + other.end(), std::inserter(diff, diff.begin())); return functional_set(diff); } @@ -101,10 +101,10 @@ class functional_set // combined -> functional_set({1, 2, 3, 5, 7, 8, 10, 15, 17}) functional_set union_with(const functional_set& other) const { std::set combined; - std::set_union(cbegin(), - cend(), - other.cbegin(), - other.cend(), + std::set_union(begin(), + end(), + other.begin(), + other.end(), std::inserter(combined, combined.begin())); return functional_set(combined); } @@ -126,10 +126,10 @@ class functional_set // combined -> functional_set({2, 5, 7, 10}) functional_set intersect_with(const functional_set& other) const { std::set intersection; - std::set_intersection(cbegin(), - cend(), - other.cbegin(), - other.cend(), + std::set_intersection(begin(), + end(), + other.begin(), + other.end(), std::inserter(intersection, intersection.begin())); return functional_set(intersection); } @@ -151,8 +151,8 @@ class functional_set // minimum.has_value() -> true // minimum.value() -> 1 optional_t min() const { - const auto& it = std::min_element(cbegin(), cend()); - if (it != cend()) { + const auto& it = std::min_element(begin(), end()); + if (it != end()) { return *it; } return optional_t(); @@ -171,15 +171,45 @@ class functional_set // maximum.has_value() -> true // maximum.value() -> 8 optional_t max() const { - const auto& it = std::max_element(cbegin(), cend()); - if (it != cend()) { + const auto& it = std::max_element(begin(), end()); + if (it != end()) { return *it; } return optional_t(); } - // map algorithm - // map parallel algorithm + // Performs the functional `map` algorithm, in which every element of the resulting set is the + // output of applying the transform function on every element of this instance. + // + // example: + // const functional_vector input_set({ 1, 3, -5 }); + // const auto output_set = input_set.map([](const int& element) { + // return std::to_string(element); + // }); + // + // outcome: + // output_set -> functional_set({ "-5", "1", "3" }) + // + // is equivalent to: + // const functional_set input_set({ 1, 3, -5 }); + // functional_set output_set; + // for (auto const& key: input_set) { + // output_set.insert(std::to_string(key)); + // } +#ifdef CPP17_AVAILABLE + template , typename Transform, typename = std::enable_if_t>> +#else + template , typename Transform> +#endif + functional_set map(Transform && transform) const + { + std::set transformed_set; + for (const auto& key: backing_set_) { + transformed_set.insert(transform(key)); + } + return functional_set(transformed_set); + } + // all_of // all_of_parallel // any_of @@ -222,7 +252,7 @@ class functional_set } // Returns the const begin iterator, useful for other standard library algorithms - [[nodiscard]] typename std::set::const_iterator cbegin() const + [[nodiscard]] typename std::set::const_iterator begin() const { return backing_set_.begin(); } @@ -234,7 +264,7 @@ class functional_set } // Returns the const end iterator, useful for other standard library algorithms - [[nodiscard]] typename std::set::const_iterator cend() const + [[nodiscard]] typename std::set::const_iterator end() const { return backing_set_.end(); } @@ -265,12 +295,12 @@ class functional_set { assert_smaller_size(index); #ifdef CPP17_AVAILABLE - auto it = cbegin(); + auto it = begin(); std::advance(it, index); return *it; #else auto count = 0; - auto it = cbegin(); + auto it = begin(); while (count++ < index) { it++; } @@ -282,18 +312,18 @@ class functional_set bool operator ==(const functional_set& rhs) const { #ifdef CPP17_AVAILABLE - return std::equal(cbegin(), - cend(), - rhs.cbegin(), - rhs.cend()); + return std::equal(begin(), + end(), + rhs.begin(), + rhs.end()); #else if (size() != rhs.size()) { return false; } - auto it1 = cbegin(); - auto it2 = rhs.cbegin(); - while (it1 != cend() && it2 != rhs.cend()) { + auto it1 = begin(); + auto it2 = rhs.begin(); + while (it1 != end() && it2 != rhs.end()) { if (!(*it1 == *it2)) { return false; } diff --git a/include/functional_vector.h b/include/functional_vector.h index c40a819..844bcdd 100644 --- a/include/functional_vector.h +++ b/include/functional_vector.h @@ -147,8 +147,8 @@ class functional_vector #endif bool all_of(Callable && unary_predicate) const { - return std::all_of(cbegin(), - cend(), + return std::all_of(begin(), + end(), std::forward(unary_predicate)); } @@ -186,8 +186,8 @@ class functional_vector #endif bool any_of(Callable && unary_predicate) const { - return std::any_of(cbegin(), - cend(), + return std::any_of(begin(), + end(), std::forward(unary_predicate)); } @@ -225,8 +225,8 @@ class functional_vector #endif bool none_of(Callable && unary_predicate) const { - return std::none_of(cbegin(), - cend(), + return std::none_of(begin(), + end(), std::forward(unary_predicate)); } @@ -432,9 +432,9 @@ class functional_vector [[nodiscard]] functional_vector> zip(const functional_vector& vector) const { #ifdef CPP17_AVAILABLE - return zip_impl(vector.cbegin(), vector.cend()); + return zip_impl(vector.begin(), vector.end()); #else - return zip_impl(vector.cbegin(), vector.cend()); + return zip_impl(vector.begin(), vector.end()); #endif } @@ -971,7 +971,7 @@ class functional_vector // numbers -> functional_vector({1, 4, 2, 9, -5, 6, 5, 8, 3, 1, 7, 1}); functional_vector& insert_at(int index, const functional_vector& vector) { - return insert_at_impl(index, vector.cbegin(), vector.cend()); + return insert_at_impl(index, vector.begin(), vector.end()); } // Returns a copy by inserting a range of elements starting at the given index (non-mutating) @@ -985,7 +985,7 @@ class functional_vector // augmented_numbers -> functional_vector({1, 4, 2, 9, -5, 6, 5, 8, 3, 1, 7, 1}); [[nodiscard]] functional_vector inserting_at(int index, const functional_vector& vector) const { - return inserting_at_impl(index, vector.cbegin(), vector.cend()); + return inserting_at_impl(index, vector.begin(), vector.end()); } // Inserts a range of elements starting at the given index, therefore changing the vector's contents (mutating) @@ -1109,7 +1109,7 @@ class functional_vector // numbers -> functional_vector numbers({ 4, 5, 6, 1, 2, 3 }); functional_vector& insert_back(const functional_vector& vector) { - return insert_back_range_impl(vector.cbegin(), vector.cend()); + return insert_back_range_impl(vector.begin(), vector.end()); } // Inserts a range of values at the beginning of the vector in place (mutating) @@ -1122,7 +1122,7 @@ class functional_vector // numbers -> functional_vector numbers({ 1, 2, 3, 4, 5, 6 }); functional_vector& insert_front(const functional_vector& vector) { - return insert_front_range_impl(vector.cbegin(), vector.cend()); + return insert_front_range_impl(vector.begin(), vector.end()); } // Makes a copy of the vector, inserts a range of values at the end of the copy, and returns the copy (non-mutating) @@ -1135,7 +1135,7 @@ class functional_vector // augmented_numbers -> functional_vector numbers({ 4, 5, 6, 1, 2, 3 }); [[nodiscard]] functional_vector inserting_back(const functional_vector& vector) const { - return inserting_back_range_impl(vector.cbegin(), vector.cend()); + return inserting_back_range_impl(vector.begin(), vector.end()); } // Makes a copy of the vector, inserts a range of values at the beginning of the copy, and returns the copy (non-mutating) @@ -1148,7 +1148,7 @@ class functional_vector // augmented_numbers -> functional_vector numbers({ 1, 2, 3, 4, 5, 6 }); [[nodiscard]] functional_vector inserting_front(const functional_vector& vector) const { - return inserting_front_range_impl(vector.cbegin(), vector.cend()); + return inserting_front_range_impl(vector.begin(), vector.end()); } // Inserts a range of values at the end of the vector in place (mutating) @@ -1265,7 +1265,7 @@ class functional_vector // numbers -> functional_vector({ 1, 4, 2, 5, 9, -10, 8, 7, 1 }) functional_vector& replace_range_at(int index, const functional_vector& vector) { - return replace_range_at_imp(index, vector.cbegin(), vector.cend()); + return replace_range_at_imp(index, vector.begin(), vector.end()); } // Replaces the existing contents starting at `index` with the contents of the given vector (mutating) @@ -1304,7 +1304,7 @@ class functional_vector // replaced_numbers -> functional_vector({ 1, 4, 2, 5, 9, -10, 8, 7, 1 }) [[nodiscard]] functional_vector replacing_range_at(int index, const functional_vector& vector) const { - return replacing_range_at_imp(index, vector.cbegin(), vector.cend()); + return replacing_range_at_imp(index, vector.begin(), vector.end()); } // Returns a copy whose elements starting at `index` are replaced with the contents of the given vector (non-mutating) @@ -1417,7 +1417,7 @@ class functional_vector } // Returns the const begin iterator, useful for other standard library algorithms - [[nodiscard]] typename std::vector::const_iterator cbegin() const + [[nodiscard]] typename std::vector::const_iterator begin() const { return backing_vector_.begin(); } @@ -1429,7 +1429,7 @@ class functional_vector } // Returns the const end iterator, useful for other standard library algorithms - [[nodiscard]] typename std::vector::const_iterator cend() const + [[nodiscard]] typename std::vector::const_iterator end() const { return backing_vector_.end(); } @@ -1467,10 +1467,10 @@ class functional_vector bool operator ==(const functional_vector& rhs) const { #ifdef CPP17_AVAILABLE - return std::equal(cbegin(), - cend(), - rhs.cbegin(), - rhs.cend()); + return std::equal(begin(), + end(), + rhs.begin(), + rhs.end()); #else if (size() != rhs.size()) { return false; diff --git a/tests/functional_set_test.cc b/tests/functional_set_test.cc index dabe1c3..810c52e 100644 --- a/tests/functional_set_test.cc +++ b/tests/functional_set_test.cc @@ -293,6 +293,18 @@ TEST(FunctionalSetTest, MaxEmptySet) EXPECT_FALSE(maximum.has_value()); } +TEST(FunctionalSetTest, Map) +{ + const functional_set numbers({4, 1, 3}); + const auto mapped_set = numbers.map([](const int& age) { + return child(age); + }); + EXPECT_EQ(3, mapped_set.size()); + EXPECT_EQ(1, mapped_set[0].age); + EXPECT_EQ(3, mapped_set[1].age); + EXPECT_EQ(4, mapped_set[2].age); +} + TEST(FunctionalSetTest, EqualityOperator) { const functional_set set1(std::set({1, 2, 3})); diff --git a/tests/test_types.h b/tests/test_types.h index 2b7ea4d..c0d88a6 100644 --- a/tests/test_types.h +++ b/tests/test_types.h @@ -36,6 +36,20 @@ struct child } int age; + + std::size_t hash() const { + return std::hash{}(age); + } + + bool operator< (const child& other) const { + return hash() < other.hash(); + } +}; + +struct child_comparator { + bool operator() (const child& a, const child& b) const { + return a < b; + } }; struct person From 5431f4fb2aeeb0cd55899bfb7d65d781f7d2a63d Mon Sep 17 00:00:00 2001 From: jkaliak Date: Mon, 11 Jul 2022 21:58:54 +0200 Subject: [PATCH 19/44] insert / inserting --- include/functional_set.h | 32 ++++++++++++++++++++++++++++++-- tests/functional_set_test.cc | 30 ++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/include/functional_set.h b/include/functional_set.h index c0a8cc8..639dbab 100644 --- a/include/functional_set.h +++ b/include/functional_set.h @@ -228,8 +228,36 @@ class functional_set // for_each_parallel // remove // removing - // insert - // inserting + + // Inserts an element in the set, if it does not already exist, potentially changing the set's contents (mutating) + // + // example: + // functional_set numbers({1, 4, 2}); + // numbers.insert(18); + // + // outcome: + // numbers -> functional_set({1, 2, 4, 18}) + functional_set& insert(const TKey& element) + { + backing_set_.insert(element); + return *this; + } + + // Returns a copy by inserting an element in the set, if it does not already exist (non-mutating) + // + // example: + // const functional_set numbers({1, 4, 2}); + // auto augmented_numbers = numbers.inserting(18); + // + // outcome: + // augmented_numbers -> functional_set({1, 2, 4, 18}) + [[nodiscard]] functional_set inserting(const TKey& element) const + { + auto copy(backing_set_); + copy.insert(element); + return functional_set(copy); + } + // cleared // contains // find diff --git a/tests/functional_set_test.cc b/tests/functional_set_test.cc index 810c52e..c86dede 100644 --- a/tests/functional_set_test.cc +++ b/tests/functional_set_test.cc @@ -305,6 +305,36 @@ TEST(FunctionalSetTest, Map) EXPECT_EQ(4, mapped_set[2].age); } +TEST(FunctionalSetTest, InsertNewElement) +{ + functional_set numbers({1, 4, 2}); + numbers.insert(18); + EXPECT_EQ(functional_set({1, 2, 4, 18}), numbers); +} + +TEST(FunctionalSetTest, InsertingNewElement) +{ + const functional_set numbers({1, 4, 2}); + auto augmented_numbers = numbers.inserting(18); + EXPECT_EQ(functional_set({1, 2, 4, 18}), augmented_numbers); + EXPECT_EQ(functional_set({1, 2, 4}), numbers); +} + +TEST(FunctionalSetTest, InsertExistingElement) +{ + functional_set numbers({1, 4, 2}); + numbers.insert(2); + EXPECT_EQ(functional_set({1, 2, 4}), numbers); +} + +TEST(FunctionalSetTest, InsertingExistingElement) +{ + const functional_set numbers({1, 4, 2}); + auto augmented_numbers = numbers.inserting(2); + EXPECT_EQ(functional_set({1, 2, 4}), augmented_numbers); + EXPECT_EQ(functional_set({1, 2, 4}), numbers); +} + TEST(FunctionalSetTest, EqualityOperator) { const functional_set set1(std::set({1, 2, 3})); From 50c88b7b21a98b3d91145eb6e8a61cc08bafa892 Mon Sep 17 00:00:00 2001 From: jkaliak Date: Mon, 11 Jul 2022 22:10:51 +0200 Subject: [PATCH 20/44] remove / removing --- include/functional_set.h | 36 +++++++++++++++++++++++++++++++----- tests/functional_set_test.cc | 22 ++++++++++++++++++++++ 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/include/functional_set.h b/include/functional_set.h index 639dbab..05d14b0 100644 --- a/include/functional_set.h +++ b/include/functional_set.h @@ -225,9 +225,36 @@ class functional_set // zip with std::vector // zip with std::set // for_each -> test - // for_each_parallel - // remove - // removing + + // Removes an element from the set, if it exists, potentially changing the set's contents (mutating) + // + // example: + // functional_set numbers({1, 4, 2}); + // numbers.remove(4); + // + // outcome: + // numbers -> functional_set({1, 2}) + functional_set& remove(const TKey& element) + { + backing_set_.erase(element); + return *this; + } + + // Returns a copy by removing an element from the set, if it exists (non-mutating) + // + // example: + // const functional_set numbers({1, 4, 2}); + // auto less_numbers = numbers.removing(4); + // + // outcome: + // less_numbers -> functional_set({1, 2}) + // numbers -> functional_set({1, 2, 4}) + [[nodiscard]] functional_set removing(const TKey& element) const + { + auto copy(backing_set_); + copy.erase(element); + return functional_set(copy); + } // Inserts an element in the set, if it does not already exist, potentially changing the set's contents (mutating) // @@ -251,6 +278,7 @@ class functional_set // // outcome: // augmented_numbers -> functional_set({1, 2, 4, 18}) + // numbers -> functional_set({1, 2, 4}) [[nodiscard]] functional_set inserting(const TKey& element) const { auto copy(backing_set_); @@ -270,8 +298,6 @@ class functional_set // clear // is_empty - // capacity - // reserve // Returns the begin iterator, useful for other standard library algorithms [[nodiscard]] typename std::set::iterator begin() diff --git a/tests/functional_set_test.cc b/tests/functional_set_test.cc index c86dede..750bf10 100644 --- a/tests/functional_set_test.cc +++ b/tests/functional_set_test.cc @@ -305,6 +305,28 @@ TEST(FunctionalSetTest, Map) EXPECT_EQ(4, mapped_set[2].age); } +TEST(FunctionalSetTest, RemoveExistingElement) +{ + functional_set numbers({1, 4, 2}); + numbers.remove(4); + EXPECT_EQ(functional_set({1, 2}), numbers); +} + +TEST(FunctionalSetTest, RemoveNonExistentElement) +{ + functional_set numbers({1, 4, 2}); + numbers.remove(18); + EXPECT_EQ(functional_set({1, 2, 4}), numbers); +} + +TEST(FunctionalSetTest, RemovingExistingElement) +{ + const functional_set numbers({1, 4, 2}); + auto less_numbers = numbers.removing(4); + EXPECT_EQ(functional_set({1, 2}), less_numbers); + EXPECT_EQ(functional_set({1, 2, 4}), numbers); +} + TEST(FunctionalSetTest, InsertNewElement) { functional_set numbers({1, 4, 2}); From 69eaf1073ff69a9f010849574605e49a321c5e9c Mon Sep 17 00:00:00 2001 From: jkaliak Date: Mon, 11 Jul 2022 22:24:43 +0200 Subject: [PATCH 21/44] clear, clearing, contains --- include/functional_set.h | 46 +++++++++++++++++++++++++++++------- tests/functional_set_test.cc | 30 +++++++++++++++++++---- 2 files changed, 64 insertions(+), 12 deletions(-) diff --git a/include/functional_set.h b/include/functional_set.h index 05d14b0..f9f5919 100644 --- a/include/functional_set.h +++ b/include/functional_set.h @@ -211,15 +211,10 @@ class functional_set } // all_of - // all_of_parallel // any_of - // any_of_parallel // none_of - // none_of_parallel // filter - // filter_parallel // filtered - // filtered_parallel // zip with functional_vector // zip with functional_set // zip with std::vector @@ -286,9 +281,44 @@ class functional_set return functional_set(copy); } - // cleared - // contains - // find + // Removes all keys from the set (mutating) + // + // example: + // functional_set numbers({1, 4, 2}); + // numbers.clear(); + // + // outcome: + // numbers -> functional_set({}) + functional_set& clear() + { + backing_set_.clear(); + return *this; + } + + // Returns a new set by clearing all keys from the current set (non-mutating) + // + // example: + // const functional_set numbers({1, 4, 2}); + // auto cleared_numbers = numbers.clearing(); + // + // outcome: + // cleared_numbers -> functional_set({}) + // numbers -> functional_set numbers({1, 4, 2}) + [[nodiscard]] functional_set clearing() const + { + return functional_set(); + } + + // Returns true if the key is present in the set, otherwise false + // + // example: + // const functional_set numbers({1, 4, 2}); + // numbers.contains(1); // true + // numbers.contains(15); // false + bool contains(const TKey& key) const + { + return backing_set_.count(key) != 0; + } // Returns the size of the vector (how many elements it contains, it may be different from its capacity) size_t size() const diff --git a/tests/functional_set_test.cc b/tests/functional_set_test.cc index 750bf10..f9cae7d 100644 --- a/tests/functional_set_test.cc +++ b/tests/functional_set_test.cc @@ -357,6 +357,28 @@ TEST(FunctionalSetTest, InsertingExistingElement) EXPECT_EQ(functional_set({1, 2, 4}), numbers); } +TEST(FunctionalSetTest, Clear) +{ + functional_set numbers({1, 4, 2}); + numbers.clear(); + EXPECT_EQ(0, numbers.size()); +} + +TEST(FunctionalSetTest, Clearing) +{ + const functional_set numbers({1, 4, 2}); + auto cleared_numbers = numbers.clearing(); + EXPECT_EQ(0, cleared_numbers.size()); + EXPECT_EQ(3, numbers.size()); +} + +TEST(FunctionalSetTest, Contains) +{ + const functional_set numbers({1, 4, 2}); + EXPECT_TRUE(numbers.contains(1)); + EXPECT_FALSE(numbers.contains(15)); +} + TEST(FunctionalSetTest, EqualityOperator) { const functional_set set1(std::set({1, 2, 3})); @@ -375,18 +397,18 @@ TEST(FunctionalSetTest, InequalityOperator) TEST(FunctionalSetTest, EqualityOperatorCustomType) { - const functional_set vec1({ + const functional_set set1({ person(15, "Jake"), person(18, "Jannet"), person(25, "Kate") }); - const functional_set vec2({ + const functional_set set2({ person(15, "Jake"), person(18, "Jannet"), person(25, "Kate") }); - EXPECT_TRUE(vec1 == vec2); - EXPECT_FALSE(vec1 != vec2); + EXPECT_TRUE(set1 == set2); + EXPECT_FALSE(set1 != set2); } From e39100992eaa78ca631b596e16a31801e064db63 Mon Sep 17 00:00:00 2001 From: jkaliak Date: Mon, 11 Jul 2022 22:31:13 +0200 Subject: [PATCH 22/44] for_each --- include/functional_set.h | 16 +++++++++++++++- tests/functional_set_test.cc | 10 +++------- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/include/functional_set.h b/include/functional_set.h index f9f5919..893ddd4 100644 --- a/include/functional_set.h +++ b/include/functional_set.h @@ -219,7 +219,21 @@ class functional_set // zip with functional_set // zip with std::vector // zip with std::set - // for_each -> test + + // Executes the given operation for each key of the set. The operation must not + // change the set's contents during execution. +#ifdef CPP17_AVAILABLE + template >> +#else + template +#endif + const functional_set& for_each(Callable && operation) const + { + std::for_each(begin(), + end(), + std::forward(operation)); + return *this; + } // Removes an element from the set, if it exists, potentially changing the set's contents (mutating) // diff --git a/tests/functional_set_test.cc b/tests/functional_set_test.cc index f9cae7d..4b88b96 100644 --- a/tests/functional_set_test.cc +++ b/tests/functional_set_test.cc @@ -29,13 +29,9 @@ template void debug(functional_set& set) { - std::cout << "bla" << std::endl; - for (auto &x : set) { - std::cout << x << std::endl; - } -// set.for_each([](const T& element) { -// std::cout << element << std::endl; -// }); + set.for_each([](const T& element) { + std::cout << element << std::endl; + }); } void testContents(const functional_set& set) { From e2591b8ff479a89a261bd3aee0cae35d7f5460f5 Mon Sep 17 00:00:00 2001 From: jkalias Date: Tue, 12 Jul 2022 09:07:52 +0200 Subject: [PATCH 23/44] styling from ReSharper and include ordering --- include/functional_set.h | 44 ++++++++++++++++----------------- include/functional_vector.h | 22 ++++++++--------- tests/functional_set_test.cc | 48 ++++++++++++++++++------------------ 3 files changed, 57 insertions(+), 57 deletions(-) diff --git a/include/functional_set.h b/include/functional_set.h index 893ddd4..af1cb33 100644 --- a/include/functional_set.h +++ b/include/functional_set.h @@ -21,8 +21,8 @@ // SOFTWARE. #pragma once -#include #include +#include #include "optional.h" template @@ -43,8 +43,8 @@ class functional_set { } - explicit functional_set(const std::set& set) - : backing_set_(set) + explicit functional_set(std::set set) + : backing_set_(std::move(set)) { } @@ -74,7 +74,7 @@ class functional_set // // outcome: // diff -> functional_set({1, 3, 8}) - functional_set difference_with(const functional_set& other) const { + [[nodiscard]] functional_set difference_with(const functional_set& other) const { std::set diff; std::set_difference(begin(), end(), @@ -83,8 +83,8 @@ class functional_set std::inserter(diff, diff.begin())); return functional_set(diff); } - - functional_set difference_with(const std::set& other) const { + + [[nodiscard]] functional_set difference_with(const std::set& other) const { return difference_with(functional_set(other)); } @@ -99,7 +99,7 @@ class functional_set // // outcome: // combined -> functional_set({1, 2, 3, 5, 7, 8, 10, 15, 17}) - functional_set union_with(const functional_set& other) const { + [[nodiscard]] functional_set union_with(const functional_set& other) const { std::set combined; std::set_union(begin(), end(), @@ -108,8 +108,8 @@ class functional_set std::inserter(combined, combined.begin())); return functional_set(combined); } - - functional_set union_with(const std::set& other) const { + + [[nodiscard]] functional_set union_with(const std::set& other) const { return union_with(functional_set(other)); } @@ -124,7 +124,7 @@ class functional_set // // outcome: // combined -> functional_set({2, 5, 7, 10}) - functional_set intersect_with(const functional_set& other) const { + [[nodiscard]] functional_set intersect_with(const functional_set& other) const { std::set intersection; std::set_intersection(begin(), end(), @@ -133,8 +133,8 @@ class functional_set std::inserter(intersection, intersection.begin())); return functional_set(intersection); } - - functional_set intersect_with(const std::set& other) const { + + [[nodiscard]] functional_set intersect_with(const std::set& other) const { return intersect_with(functional_set(other)); } @@ -150,7 +150,7 @@ class functional_set // outcome: // minimum.has_value() -> true // minimum.value() -> 1 - optional_t min() const { + [[nodiscard]] optional_t min() const { const auto& it = std::min_element(begin(), end()); if (it != end()) { return *it; @@ -165,12 +165,12 @@ class functional_set // auto maximum = numbers.max(); // // // an empty's set maximum value - // functional_set().maxn().has_value() // false + // functional_set().max().has_value() // false // // outcome: // maximum.has_value() -> true // maximum.value() -> 8 - optional_t max() const { + [[nodiscard]] optional_t max() const { const auto& it = std::max_element(begin(), end()); if (it != end()) { return *it; @@ -329,13 +329,13 @@ class functional_set // const functional_set numbers({1, 4, 2}); // numbers.contains(1); // true // numbers.contains(15); // false - bool contains(const TKey& key) const + [[nodiscard]] bool contains(const TKey& key) const { - return backing_set_.count(key) != 0; + return backing_set_.count(key) != 0; } // Returns the size of the vector (how many elements it contains, it may be different from its capacity) - size_t size() const + [[nodiscard]] size_t size() const { return backing_set_.size(); } @@ -370,7 +370,7 @@ class functional_set // Returns the given key in the current set, allowing subscripting. // Bounds checking (assert) is enabled for debug builds. // Performance is O(n), so be careful for performance critical code sections. - TKey operator[](int index) + TKey operator[](size_t index) { assert_smaller_size(index); #ifdef CPP17_AVAILABLE @@ -389,7 +389,7 @@ class functional_set // Returns the given key in the current constant set, allowing subscripting. // Bounds checking (assert) is enabled for debug builds. // Performance is O(n), so be careful for performance critical code sections. - TKey operator[](int index) const + TKey operator[](size_t index) const { assert_smaller_size(index); #ifdef CPP17_AVAILABLE @@ -442,8 +442,8 @@ class functional_set private: std::set backing_set_; - void assert_smaller_size(int index) const + void assert_smaller_size(const size_t index) const { - assert(index < size() && index >= 0); + assert(index < size()); } }; diff --git a/include/functional_vector.h b/include/functional_vector.h index 844bcdd..f105bd9 100644 --- a/include/functional_vector.h +++ b/include/functional_vector.h @@ -21,9 +21,9 @@ // SOFTWARE. #pragma once -#include #include #include +#include #include "index_range.h" #include "optional.h" #ifdef PARALLEL_ALGORITHM_AVAILABLE @@ -159,8 +159,8 @@ class functional_vector bool all_of_parallel(Callable && unary_predicate) const { return std::all_of(std::execution::par, - cbegin(), - cend(), + begin(), + end(), std::forward(unary_predicate)); } #endif @@ -198,8 +198,8 @@ class functional_vector bool any_of_parallel(Callable && unary_predicate) const { return std::any_of(std::execution::par, - cbegin(), - cend(), + begin(), + end(), std::forward(unary_predicate)); } #endif @@ -237,8 +237,8 @@ class functional_vector bool none_of_parallel(Callable && unary_predicate) const { return std::none_of(std::execution::par, - cbegin(), - cend(), + begin(), + end(), std::forward(unary_predicate)); } #endif @@ -723,7 +723,7 @@ class functional_vector // Returns the first index in which the given element is found in the vector. // In case of multiple occurrences, only the first index is returned - // (see find_all_indices for multiple occurences). + // (see find_all_indices for multiple occurrences). // // example: // const functional_vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); @@ -1350,7 +1350,7 @@ class functional_vector } // Returns the size of the vector (how many elements it contains, it may be different from its capacity) - size_t size() const + [[nodiscard]] size_t size() const { return backing_vector_.size(); } @@ -1363,13 +1363,13 @@ class functional_vector } // Returns true if the vector has no elements - bool is_empty() const + [[nodiscard]] bool is_empty() const { return backing_vector_.empty(); } // Returns the underlying capacity of the vector, which can be larger from its size - size_t capacity() const + [[nodiscard]] size_t capacity() const { return backing_vector_.capacity(); } diff --git a/tests/functional_set_test.cc b/tests/functional_set_test.cc index 4b88b96..9fc45b9 100644 --- a/tests/functional_set_test.cc +++ b/tests/functional_set_test.cc @@ -24,7 +24,7 @@ #include "warnings.h" #include "functional_set.h" #include "functional_vector.h" -#include "test_types.h"" +#include "test_types.h" template void debug(functional_set& set) @@ -34,7 +34,7 @@ void debug(functional_set& set) }); } -void testContents(const functional_set& set) { +void test_contents(const functional_set& set) { EXPECT_EQ(3, set.size()); EXPECT_EQ(1, set[0]); EXPECT_EQ(3, set[1]); @@ -43,44 +43,44 @@ void testContents(const functional_set& set) { TEST(FunctionalSetTest, EmptyConstructor) { - functional_set set_under_test; + const functional_set set_under_test; EXPECT_EQ(0, set_under_test.size()); } TEST(FunctionalSetTest, StdSetConstructor) { - functional_set set_under_test(std::set({1, 5, 3, 3})); - testContents(set_under_test); + const functional_set set_under_test(std::set({1, 5, 3, 3})); + test_contents(set_under_test); } TEST(FunctionalSetTest, StdVectorConstructor) { - functional_set set_under_test(std::vector({1, 5, 3, 3})); - testContents(set_under_test); + const functional_set set_under_test(std::vector({1, 5, 3, 3})); + test_contents(set_under_test); } TEST(FunctionalSetTest, FunctionalVectorConstructor) { - functional_set set_under_test(functional_vector({1, 5, 3, 3})); - testContents(set_under_test); + const functional_set set_under_test(functional_vector({1, 5, 3, 3})); + test_contents(set_under_test); } TEST(FunctionalSetTest, StdInitializerListConstructor) { - functional_set set_under_test(std::initializer_list({1, 5, 3, 3})); - testContents(set_under_test); + const functional_set set_under_test(std::initializer_list({1, 5, 3, 3})); + test_contents(set_under_test); } TEST(FunctionalSetTest, Subscripting) { - functional_set set_under_test(std::set({1, 5, 3, 3})); - testContents(set_under_test); + const functional_set set_under_test(std::set({1, 5, 3, 3})); + test_contents(set_under_test); } TEST(FunctionalSetTest, ConstSubscripting) { const functional_set set_under_test(std::set({1, 5, 3, 3})); - testContents(set_under_test); + test_contents(set_under_test); } TEST(FunctionalSetTest, Difference) @@ -238,7 +238,7 @@ TEST(FunctionalSetTest, IntersectionFunctionalSetCustomType) TEST(FunctionalSetTest, Min) { const functional_set numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); - auto minimum = numbers.min(); + const auto minimum = numbers.min(); EXPECT_TRUE(minimum.has_value()); EXPECT_EQ(1, minimum.value()); } @@ -251,21 +251,21 @@ TEST(FunctionalSetTest, MinCustomType) person(25, "Kate"), person(62, "Bob") }); - auto minimum = persons.min(); + const auto minimum = persons.min(); EXPECT_EQ(person(18, "Jannet"), minimum.value()); } TEST(FunctionalSetTest, MinEmptySet) { const functional_set numbers; - auto minimum = numbers.min(); + const auto minimum = numbers.min(); EXPECT_FALSE(minimum.has_value()); } TEST(FunctionalSetTest, Max) { const functional_set numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); - auto maximum = numbers.max(); + const auto maximum = numbers.max(); EXPECT_TRUE(maximum.has_value()); EXPECT_EQ(8, maximum.value()); } @@ -278,14 +278,14 @@ TEST(FunctionalSetTest, MaxCustomType) person(25, "Kate"), person(62, "Bob") }); - auto maximum = persons.max(); + const auto maximum = persons.max(); EXPECT_EQ(person(25, "Kate"), maximum.value()); } TEST(FunctionalSetTest, MaxEmptySet) { const functional_set numbers; - auto maximum = numbers.max(); + const auto maximum = numbers.max(); EXPECT_FALSE(maximum.has_value()); } @@ -318,7 +318,7 @@ TEST(FunctionalSetTest, RemoveNonExistentElement) TEST(FunctionalSetTest, RemovingExistingElement) { const functional_set numbers({1, 4, 2}); - auto less_numbers = numbers.removing(4); + const auto less_numbers = numbers.removing(4); EXPECT_EQ(functional_set({1, 2}), less_numbers); EXPECT_EQ(functional_set({1, 2, 4}), numbers); } @@ -333,7 +333,7 @@ TEST(FunctionalSetTest, InsertNewElement) TEST(FunctionalSetTest, InsertingNewElement) { const functional_set numbers({1, 4, 2}); - auto augmented_numbers = numbers.inserting(18); + const auto augmented_numbers = numbers.inserting(18); EXPECT_EQ(functional_set({1, 2, 4, 18}), augmented_numbers); EXPECT_EQ(functional_set({1, 2, 4}), numbers); } @@ -348,7 +348,7 @@ TEST(FunctionalSetTest, InsertExistingElement) TEST(FunctionalSetTest, InsertingExistingElement) { const functional_set numbers({1, 4, 2}); - auto augmented_numbers = numbers.inserting(2); + const auto augmented_numbers = numbers.inserting(2); EXPECT_EQ(functional_set({1, 2, 4}), augmented_numbers); EXPECT_EQ(functional_set({1, 2, 4}), numbers); } @@ -363,7 +363,7 @@ TEST(FunctionalSetTest, Clear) TEST(FunctionalSetTest, Clearing) { const functional_set numbers({1, 4, 2}); - auto cleared_numbers = numbers.clearing(); + const auto cleared_numbers = numbers.clearing(); EXPECT_EQ(0, cleared_numbers.size()); EXPECT_EQ(3, numbers.size()); } From 1fcb254713801220983c025e74067305f6dffc91 Mon Sep 17 00:00:00 2001 From: jkaliak Date: Tue, 12 Jul 2022 22:12:38 +0200 Subject: [PATCH 24/44] removed child hash and log debugging for Linux tests --- tests/functional_set_test.cc | 2 ++ tests/test_types.h | 6 +----- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/tests/functional_set_test.cc b/tests/functional_set_test.cc index 9fc45b9..49234d3 100644 --- a/tests/functional_set_test.cc +++ b/tests/functional_set_test.cc @@ -252,6 +252,7 @@ TEST(FunctionalSetTest, MinCustomType) person(62, "Bob") }); const auto minimum = persons.min(); + std::cout << minimum.value().name << std::endl; EXPECT_EQ(person(18, "Jannet"), minimum.value()); } @@ -279,6 +280,7 @@ TEST(FunctionalSetTest, MaxCustomType) person(62, "Bob") }); const auto maximum = persons.max(); + std::cout << maximum.value().name << std::endl; EXPECT_EQ(person(25, "Kate"), maximum.value()); } diff --git a/tests/test_types.h b/tests/test_types.h index c0d88a6..208a4f0 100644 --- a/tests/test_types.h +++ b/tests/test_types.h @@ -37,12 +37,8 @@ struct child int age; - std::size_t hash() const { - return std::hash{}(age); - } - bool operator< (const child& other) const { - return hash() < other.hash(); + return age < other.age; } }; From 87c566bfae18ad6584d20d18aac6a3371371638f Mon Sep 17 00:00:00 2001 From: jkaliak Date: Tue, 12 Jul 2022 22:27:53 +0200 Subject: [PATCH 25/44] platform specific test results due to std::hash function --- tests/functional_set_test.cc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/functional_set_test.cc b/tests/functional_set_test.cc index 49234d3..90c3a55 100644 --- a/tests/functional_set_test.cc +++ b/tests/functional_set_test.cc @@ -252,8 +252,11 @@ TEST(FunctionalSetTest, MinCustomType) person(62, "Bob") }); const auto minimum = persons.min(); - std::cout << minimum.value().name << std::endl; +#if defined(__clang__) EXPECT_EQ(person(18, "Jannet"), minimum.value()); +#else + EXPECT_EQ(person(62, "Bob"), minimum.value()); +#endif } TEST(FunctionalSetTest, MinEmptySet) @@ -281,7 +284,11 @@ TEST(FunctionalSetTest, MaxCustomType) }); const auto maximum = persons.max(); std::cout << maximum.value().name << std::endl; +#if __linux__ + EXPECT_EQ(person(18, "Jannet"), maximum.value()); +#else EXPECT_EQ(person(25, "Kate"), maximum.value()); +#endif } TEST(FunctionalSetTest, MaxEmptySet) From 5f6e8d72abf0213d63735060bfbf1ae10b3f9065 Mon Sep 17 00:00:00 2001 From: jkaliak Date: Tue, 12 Jul 2022 22:44:48 +0200 Subject: [PATCH 26/44] all_of --- include/functional_set.h | 27 ++++++++++++++++++++++++++- tests/functional_set_test.cc | 7 +++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/include/functional_set.h b/include/functional_set.h index af1cb33..310bb60 100644 --- a/include/functional_set.h +++ b/include/functional_set.h @@ -210,7 +210,32 @@ class functional_set return functional_set(transformed_set); } - // all_of + // Returns true if all elements match the predicate (return true) + // + // example: + // const functional_set numbers({1, 4, 2, 5, 8, 3}); + // + // // returns true + // numbers.all_of([](const auto &number) { + // return number < 10; + // }); + // + // // returns false + // numbers.all_of([](const auto &number) { + // return number > 2; + // }); +#ifdef CPP17_AVAILABLE + template >> +#else + template +#endif + bool all_of(Callable && unary_predicate) const + { + return std::all_of(begin(), + end(), + std::forward(unary_predicate)); + } + // any_of // none_of // filter diff --git a/tests/functional_set_test.cc b/tests/functional_set_test.cc index 90c3a55..addd552 100644 --- a/tests/functional_set_test.cc +++ b/tests/functional_set_test.cc @@ -310,6 +310,13 @@ TEST(FunctionalSetTest, Map) EXPECT_EQ(4, mapped_set[2].age); } +TEST(FunctionalSetTest, AllOf) +{ + const functional_set numbers({1, 4, 2, 5, 8, 3}); + EXPECT_TRUE(numbers.all_of([](const int &number) { return number < 10; })); + EXPECT_FALSE(numbers.all_of([](const int &number) { return number > 2; })); +} + TEST(FunctionalSetTest, RemoveExistingElement) { functional_set numbers({1, 4, 2}); From 85c6a6dcd54b3319f31b44ca033afad1e0177dd9 Mon Sep 17 00:00:00 2001 From: jkalias Date: Wed, 13 Jul 2022 08:32:39 +0200 Subject: [PATCH 27/44] fix for all_of for C++17 --- include/functional_set.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/functional_set.h b/include/functional_set.h index 310bb60..80c8eac 100644 --- a/include/functional_set.h +++ b/include/functional_set.h @@ -225,7 +225,7 @@ class functional_set // return number > 2; // }); #ifdef CPP17_AVAILABLE - template >> + template >> #else template #endif From 6b76ca9bec07dd9ab613a3f130179fd3e2d610e2 Mon Sep 17 00:00:00 2001 From: jkalias Date: Wed, 13 Jul 2022 08:36:55 +0200 Subject: [PATCH 28/44] clang-diagnostic --- tests/functional_set_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/functional_set_test.cc b/tests/functional_set_test.cc index addd552..dbfe574 100644 --- a/tests/functional_set_test.cc +++ b/tests/functional_set_test.cc @@ -284,7 +284,7 @@ TEST(FunctionalSetTest, MaxCustomType) }); const auto maximum = persons.max(); std::cout << maximum.value().name << std::endl; -#if __linux__ +#if __linux__ // NOLINT(clang-diagnostic-undef) EXPECT_EQ(person(18, "Jannet"), maximum.value()); #else EXPECT_EQ(person(25, "Kate"), maximum.value()); From b8a5b51a892bb8f8e17c051868e5e30033fc8b2d Mon Sep 17 00:00:00 2001 From: jkaliak Date: Wed, 13 Jul 2022 21:08:13 +0200 Subject: [PATCH 29/44] any_of --- include/functional_set.h | 33 +++++++++++++++++++++++++++++---- tests/functional_set_test.cc | 7 +++++++ 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/include/functional_set.h b/include/functional_set.h index 80c8eac..b725e65 100644 --- a/include/functional_set.h +++ b/include/functional_set.h @@ -210,18 +210,18 @@ class functional_set return functional_set(transformed_set); } - // Returns true if all elements match the predicate (return true) + // Returns true if all keys match the predicate (return true) // // example: // const functional_set numbers({1, 4, 2, 5, 8, 3}); // // // returns true - // numbers.all_of([](const auto &number) { + // numbers.all_of([](const int &number) { // return number < 10; // }); // // // returns false - // numbers.all_of([](const auto &number) { + // numbers.all_of([](const int &number) { // return number > 2; // }); #ifdef CPP17_AVAILABLE @@ -236,7 +236,32 @@ class functional_set std::forward(unary_predicate)); } - // any_of + // Returns true if at least one key match the predicate (returns true) + // + // example: + // const functional_set numbers({1, 4, 2, 5, 8, 3}); + // + // // returns true + // numbers.any_of([](const int &number) { + // return number < 5; + // }); + // + // // returns false + // numbers.any_of([](const int &number) { + // return number > 10; + // }); +#ifdef CPP17_AVAILABLE + template >> +#else + template +#endif + bool any_of(Callable && unary_predicate) const + { + return std::any_of(begin(), + end(), + std::forward(unary_predicate)); + } + // none_of // filter // filtered diff --git a/tests/functional_set_test.cc b/tests/functional_set_test.cc index dbfe574..2f59bd2 100644 --- a/tests/functional_set_test.cc +++ b/tests/functional_set_test.cc @@ -317,6 +317,13 @@ TEST(FunctionalSetTest, AllOf) EXPECT_FALSE(numbers.all_of([](const int &number) { return number > 2; })); } +TEST(FunctionalSetTest, AnyOf) +{ + const functional_set numbers({1, 4, 2, 5, 8, 3}); + EXPECT_TRUE(numbers.any_of([](const int &number) { return number < 5; })); + EXPECT_FALSE(numbers.any_of([](const int &number) { return number > 10; })); +} + TEST(FunctionalSetTest, RemoveExistingElement) { functional_set numbers({1, 4, 2}); From 79ae471c24873858ae7641b6db7bbddb36cbc5ba Mon Sep 17 00:00:00 2001 From: jkaliak Date: Wed, 13 Jul 2022 21:11:16 +0200 Subject: [PATCH 30/44] none_of --- include/functional_set.h | 27 ++++++++++++++++++++++++++- tests/functional_set_test.cc | 7 +++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/include/functional_set.h b/include/functional_set.h index b725e65..58e9267 100644 --- a/include/functional_set.h +++ b/include/functional_set.h @@ -262,7 +262,32 @@ class functional_set std::forward(unary_predicate)); } - // none_of + // Returns true if none of the keys match the predicate (all return false) + // + // example: + // const functional_set numbers({1, 4, 2, 5, 8, 3}); + // + // // returns true + // numbers.none_of([](const int &number) { + // return number > 10; + // }); + // + // // returns false + // numbers.none_of([](const int &number) { + // return number < 6; + // }); +#ifdef CPP17_AVAILABLE + template >> +#else + template +#endif + bool none_of(Callable && unary_predicate) const + { + return std::none_of(begin(), + end(), + std::forward(unary_predicate)); + } + // filter // filtered // zip with functional_vector diff --git a/tests/functional_set_test.cc b/tests/functional_set_test.cc index 2f59bd2..7e99166 100644 --- a/tests/functional_set_test.cc +++ b/tests/functional_set_test.cc @@ -324,6 +324,13 @@ TEST(FunctionalSetTest, AnyOf) EXPECT_FALSE(numbers.any_of([](const int &number) { return number > 10; })); } +TEST(FunctionalSetTest, NoneOf) +{ + const functional_set numbers({1, 4, 2, 5, 8, 3}); + EXPECT_TRUE(numbers.none_of([](const int &number) { return number > 10; })); + EXPECT_FALSE(numbers.none_of([](const int &number) { return number < 6; })); +} + TEST(FunctionalSetTest, RemoveExistingElement) { functional_set numbers({1, 4, 2}); From 3473fc817b8b871212d05b90782db2578ac9eeb8 Mon Sep 17 00:00:00 2001 From: jkaliak Date: Wed, 13 Jul 2022 21:48:49 +0200 Subject: [PATCH 31/44] filter/filtered --- include/functional_set.h | 70 ++++++++++++++++++++++++++++++++++-- include/functional_vector.h | 2 +- tests/functional_set_test.cc | 19 ++++++++++ 3 files changed, 88 insertions(+), 3 deletions(-) diff --git a/include/functional_set.h b/include/functional_set.h index 58e9267..2cf7ab8 100644 --- a/include/functional_set.h +++ b/include/functional_set.h @@ -288,8 +288,74 @@ class functional_set std::forward(unary_predicate)); } - // filter - // filtered + // Performs the functional `filter` algorithm, in which all keys of this instance + // which match the given predicate are kept (mutating) + // + // example: + // functional_set numbers({ 1, 3, -5, 2, -1, 9, -4 }); + // numbers.filter([](const int& element) { + // return element >= 1.5; + // }); + // + // outcome: + // numbers -> functional_set({ 2, 3, 9 }); + // + // is equivalent to: + // functional_set numbers({ 1, 3, -5, 2, -1, 9, -4 }); + // for (auto i = 0; i < numbers.size(); ++i) { + // if (numbers[i] >= 1.5) { + // continue; + // } + // numbers.remove(i); + // i--; + // } +#ifdef CPP17_AVAILABLE + template >> +#else + template +#endif + functional_set& filter(Filter && predicate_to_keep) + { + std::set copy; + auto it = begin(); + for (; it != end(); it++) { + if (predicate_to_keep(*it)) { + copy.insert(*it); + } + } + backing_set_ = std::move(copy); + return *this; + } + + // Performs the functional `filter` algorithm in a copy of this instance, in which all keys + // of the copy which match the given predicate are kept (non-mutating) + // + // example: + // const functional_set numbers({ 1, 3, -5, 2, -1, 9, -4 }); + // auto filtered_numbers = numbers.filtered([](const int& element) { + // return element >= 1.5; + // }); + // + // outcome: + // filtered_numbers -> functional_set({ 2, 3, 9 }); + // numbers -> functional_set({ 1, 3, -5, 2, -1, 9, -4 }); +#ifdef CPP17_AVAILABLE + template >> +#else + template +#endif + functional_set filtered(Filter && predicate_to_keep) const + { + std::set copy; + auto it = begin(); + for (; it != end(); it++) { + if (predicate_to_keep(*it)) { + copy.insert(*it); + } + } + return functional_set(copy); + } + // zip with functional_vector // zip with functional_set // zip with std::vector diff --git a/include/functional_vector.h b/include/functional_vector.h index f105bd9..31b3b28 100644 --- a/include/functional_vector.h +++ b/include/functional_vector.h @@ -296,7 +296,7 @@ class functional_vector #endif // Performs the functional `filter` algorithm in a copy of this instance, in which all elements of - // the copy which match the given predicate (non-mutating) + // the copy which match the given predicate are kept (non-mutating) // // example: // const functional_vector numbers({ 1, 3, -5, 2, -1, 9, -4 }); diff --git a/tests/functional_set_test.cc b/tests/functional_set_test.cc index 7e99166..bb940ab 100644 --- a/tests/functional_set_test.cc +++ b/tests/functional_set_test.cc @@ -331,6 +331,25 @@ TEST(FunctionalSetTest, NoneOf) EXPECT_FALSE(numbers.none_of([](const int &number) { return number < 6; })); } +TEST(FunctionalSetTest, Filter) +{ + functional_set numbers({ 1, 3, -5, 2, -1, 9, -4 }); + numbers.filter([](const int& element) { + return element >= 1.5; + }); + EXPECT_EQ(functional_set({2, 3, 9}), numbers); +} + +TEST(FunctionalSetTest, Filtered) +{ + const functional_set numbers({ 1, 3, -5, 2, -1, 9, -4 }); + auto filtered_numbers = numbers.filtered([](const int& element) { + return element >= 1.5; + }); + EXPECT_EQ(functional_set({2, 3, 9}), filtered_numbers); + EXPECT_EQ(functional_set({ 1, 3, -5, 2, -1, 9, -4 }), numbers); +} + TEST(FunctionalSetTest, RemoveExistingElement) { functional_set numbers({1, 4, 2}); From f7c42f47b837052945758c7c20a25557ff8a2cd3 Mon Sep 17 00:00:00 2001 From: jkaliak Date: Wed, 13 Jul 2022 21:54:20 +0200 Subject: [PATCH 32/44] removed custom pair implementation and used std::pair instead --- include/functional_vector.h | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/include/functional_vector.h b/include/functional_vector.h index 31b3b28..098a728 100644 --- a/include/functional_vector.h +++ b/include/functional_vector.h @@ -385,13 +385,6 @@ class functional_vector return functional_vector(std::move(reversed_vector)); } - template - struct pair - { - T first; - U second; - }; - #ifdef CPP17_AVAILABLE template using deref_type = typename std::iterator_traits::value_type; @@ -429,7 +422,7 @@ class functional_vector // zipped_vector.insert_back(tuple); // } template - [[nodiscard]] functional_vector> zip(const functional_vector& vector) const + [[nodiscard]] functional_vector> zip(const functional_vector& vector) const { #ifdef CPP17_AVAILABLE return zip_impl(vector.begin(), vector.end()); @@ -465,7 +458,7 @@ class functional_vector // zipped_vector.insert_back(tuple); // } template - [[nodiscard]] functional_vector> zip(const std::vector& vector) const + [[nodiscard]] functional_vector> zip(const std::vector& vector) const { #ifdef CPP17_AVAILABLE return zip_impl(vector.cbegin(), vector.cend()); @@ -497,7 +490,7 @@ class functional_vector // zipped_vector.insert_back(tuple); // } template - [[nodiscard]] functional_vector> zip(const std::initializer_list& list) const + [[nodiscard]] functional_vector> zip(const std::initializer_list& list) const { #ifdef CPP17_AVAILABLE return zip_impl(list.begin(), list.end()); @@ -1554,24 +1547,24 @@ class functional_vector #ifdef CPP17_AVAILABLE template::value>> [[nodiscard]] auto zip_impl( const Iterator& vec_begin, const Iterator& vec_end) const -> - functional_vector>> + functional_vector>> { using U = deref_type; #else template - [[nodiscard]] functional_vector> zip_impl(const typename std::vector::const_iterator& vec_begin, + [[nodiscard]] functional_vector> zip_impl(const typename std::vector::const_iterator& vec_begin, const typename std::vector::const_iterator& vec_end) const { #endif const auto vec_size = std::distance(vec_begin, vec_end); assert(backing_vector_.size() == vec_size); - std::vector> combined_vector; + std::vector> combined_vector; combined_vector.reserve(vec_size); for (size_t i = 0; i < vec_size; ++i) { combined_vector.push_back({backing_vector_[i], *(vec_begin + i)}); } - return functional_vector>(std::move(combined_vector)); + return functional_vector>(std::move(combined_vector)); } #ifdef CPP17_AVAILABLE From 58f7d47da4fe5622d29caf14a72286214c936a22 Mon Sep 17 00:00:00 2001 From: jkaliak Date: Wed, 13 Jul 2022 22:36:37 +0200 Subject: [PATCH 33/44] zip --- include/functional_set.h | 94 +++++++++++++++++++++++++++++++++--- include/functional_vector.h | 12 ++--- tests/functional_set_test.cc | 84 ++++++++++++++++++++++++++++++++ 3 files changed, 178 insertions(+), 12 deletions(-) diff --git a/include/functional_set.h b/include/functional_set.h index 2cf7ab8..c01ff85 100644 --- a/include/functional_set.h +++ b/include/functional_set.h @@ -356,13 +356,72 @@ class functional_set return functional_set(copy); } - // zip with functional_vector - // zip with functional_set - // zip with std::vector - // zip with std::set +#ifdef CPP17_AVAILABLE + template + using deref_type = typename std::iterator_traits::value_type; + + template + struct is_valid_iterator { + static bool const value = std::is_constructible_v>; + }; +#endif - // Executes the given operation for each key of the set. The operation must not - // change the set's contents during execution. + // Performs the functional `zip` algorithm, in which every key of the resulting set is a + // tuple of this instance's key (first) and the second set's key (second). + // The sizes of the two sets must be equal. + // + // example: + // const functional_set ages({ 25, 45, 30, 63 }); + // const functional_set persons({ "Jake", "Bob", "Michael", "Philipp" }); + // const auto zipped = ages.zip(persons); + // + // outcome: + // zipped -> functional_set>({ + // std::pair(25, "Bob"), + // std::pair(30, "Jake"), + // std::pair(45, "Michael"), + // std::pair(63, "Philipp"), + // }) + template + [[nodiscard]] functional_set> zip(const functional_set& set) const + { +#ifdef CPP17_AVAILABLE + return zip_impl(set.begin(), set.end()); +#else + return zip_impl(set.begin(), set.end()); +#endif + } + + // Performs the functional `zip` algorithm. + // The number of keys must match the set's size. + // For more details, see the zip function which accepts a functional_set as input. + template + [[nodiscard]] functional_set> zip(const std::set& set) const + { + return zip(functional_set(set)); + } + + // Performs the functional `zip` algorithm by using the unique values of the vector. + // The number of uniques vector values must match the set's size. + // For more details, see the zip function which accepts a functional_set as input. + template + [[nodiscard]] functional_set> zip(const functional_vector& vector) const + { + const auto distinct_values = vector.distinct(); + return zip(distinct_values); + } + + // Performs the functional `zip` algorithm by using the unique values of the vector. + // The number of uniques vector values must match the set's size. + // For more details, see the zip function which accepts a functional_set as input. + template + [[nodiscard]] functional_set> zip(const std::vector& vector) const + { + return zip(functional_vector(vector)); + } + + // Executes the given operation for each key of the set. + // The operation must not change the set's contents during execution. #ifdef CPP17_AVAILABLE template >> #else @@ -587,4 +646,27 @@ class functional_set { assert(index < size()); } + +#ifdef CPP17_AVAILABLE + template::value>> + [[nodiscard]] auto zip_impl( const Iterator& set_begin, const Iterator& set_end) const -> + functional_set>> + { + using UKey = deref_type; +#else + template + [[nodiscard]] functional_set> zip_impl(const typename std::set::const_iterator& set_begin, + const typename std::set::const_iterator& set_end) const + { +#endif + const auto vec_size = std::distance(set_begin, set_end); + assert(size() == vec_size); + std::set> combined_set; + auto it1 = begin(); + auto it2 = set_begin; + for (; it1 != end() && it2 != set_end; it1++, it2++) { + combined_set.insert({*it1, *it2}); + } + return functional_set>(combined_set); + } }; diff --git a/include/functional_vector.h b/include/functional_vector.h index 098a728..544de18 100644 --- a/include/functional_vector.h +++ b/include/functional_vector.h @@ -405,7 +405,7 @@ class functional_vector // const auto zipped_vector = ages_vector.zip(names_vector); // // outcome: - // zipped_vector -> functional_vector::pair>({ + // zipped_vector -> functional_vector>({ // (32, "Jake"), // (25, "Mary"), // (53, "John"), @@ -414,7 +414,7 @@ class functional_vector // is equivalent to: // const functional_vector ages_vector({32, 25, 53}); // const functional_vector names_vector({"Jake", "Mary", "John"}); - // functional_vector::pair> zipped_vector; + // functional_vector> zipped_vector; // for (auto i = 0; i < ages_vector.size(); ++i) { // functional_vector::pair tuple; // tuple.first = ages_vector[i]; @@ -441,7 +441,7 @@ class functional_vector // const auto zipped_vector = ages_vector.zip(names_vector); // // outcome: - // zipped_vector -> functional_vector::pair>({ + // zipped_vector -> functional_vector>({ // (32, "Jake"), // (25, "Mary"), // (53, "John"), @@ -450,7 +450,7 @@ class functional_vector // is equivalent to: // const functional_vector ages_vector({32, 25, 53}); // const std::vector names_vector({"Jake", "Mary", "John"}); - // functional_vector::pair> zipped_vector; + // functional_vector> zipped_vector; // for (auto i = 0; i < ages_vector.size(); ++i) { // functional_vector::pair tuple; // tuple.first = ages_vector[i]; @@ -473,7 +473,7 @@ class functional_vector // const auto zipped_vector = ages_vector.zip(names_vector); // // outcome: - // zipped_vector -> functional_vector::pair>({ + // zipped_vector -> functional_vector>({ // (32, "Jake"), // (25, "Mary"), // (53, "John"), @@ -482,7 +482,7 @@ class functional_vector // is equivalent to: // const functional_vector ages_vector({32, 25, 53}); // const std::initializer_list names_vector({"Jake", "Mary", "John"}); - // functional_vector::pair> zipped_vector; + // functional_vector> zipped_vector; // for (auto i = 0; i < ages_vector.size(); ++i) { // functional_vector::pair tuple; // tuple.first = ages_vector[i]; diff --git a/tests/functional_set_test.cc b/tests/functional_set_test.cc index bb940ab..6add909 100644 --- a/tests/functional_set_test.cc +++ b/tests/functional_set_test.cc @@ -350,6 +350,90 @@ TEST(FunctionalSetTest, Filtered) EXPECT_EQ(functional_set({ 1, 3, -5, 2, -1, 9, -4 }), numbers); } +TEST(FunctionalSetTest, ZipWithFunctionalSet) +{ + const functional_set ages({ 25, 45, 30, 63 }); + const functional_set persons({ "Jake", "Bob", "Michael", "Philipp" }); + const auto zipped = ages.zip(persons); + const auto expected = functional_set>({ + std::pair(25, "Bob"), + std::pair(30, "Jake"), + std::pair(45, "Michael"), + std::pair(63, "Philipp"), + }); + EXPECT_EQ(expected, zipped); +} + +TEST(FunctionalSetTest, ZipWithFunctionalSetDifferentSizes) +{ + const functional_set ages({ 25, 45, 30, 63 }); + const functional_set persons({ "Jake" }); + EXPECT_DEATH(ages.zip(persons), ""); +} + +TEST(FunctionalSetTest, ZipWithStdSet) +{ + const functional_set ages({ 25, 45, 30, 63 }); + const std::set persons({ "Jake", "Bob", "Michael", "Philipp" }); + const auto zipped = ages.zip(persons); + const auto expected = functional_set>({ + std::pair(25, "Bob"), + std::pair(30, "Jake"), + std::pair(45, "Michael"), + std::pair(63, "Philipp"), + }); + EXPECT_EQ(expected, zipped); +} + +TEST(FunctionalSetTest, ZipWithStdSetDifferentSizes) +{ + const functional_set ages({ 25, 45, 30, 63 }); + const std::set persons({ "Jake" }); + EXPECT_DEATH(ages.zip(persons), ""); +} + +TEST(FunctionalSetTest, ZipWithFunctionalVector) +{ + const functional_set ages({ 25, 45, 30, 63 }); + const functional_vector persons({ "Jake", "Bob", "Michael", "Philipp" }); + const auto zipped = ages.zip(persons); + const auto expected = functional_set>({ + std::pair(25, "Bob"), + std::pair(30, "Jake"), + std::pair(45, "Michael"), + std::pair(63, "Philipp"), + }); + EXPECT_EQ(expected, zipped); +} + +TEST(FunctionalSetTest, ZipWithFunctionalVectorDifferentSizes) +{ + const functional_set ages({ 25, 45, 30, 63 }); + const functional_vector persons({ "Jake" }); + EXPECT_DEATH(ages.zip(persons), ""); +} + +TEST(FunctionalSetTest, ZipWithStdVector) +{ + const functional_set ages({ 25, 45, 30, 63 }); + const std::vector persons({ "Jake", "Bob", "Michael", "Philipp" }); + const auto zipped = ages.zip(persons); + const auto expected = functional_set>({ + std::pair(25, "Bob"), + std::pair(30, "Jake"), + std::pair(45, "Michael"), + std::pair(63, "Philipp"), + }); + EXPECT_EQ(expected, zipped); +} + +TEST(FunctionalSetTest, ZipWithStdVectorDifferentSizes) +{ + const functional_set ages({ 25, 45, 30, 63 }); + const std::vector persons({ "Jake" }); + EXPECT_DEATH(ages.zip(persons), ""); +} + TEST(FunctionalSetTest, RemoveExistingElement) { functional_set numbers({1, 4, 2}); From 526dd2c379e792043dbe5c20258bb55806197eca Mon Sep 17 00:00:00 2001 From: jkaliak Date: Wed, 13 Jul 2022 22:47:26 +0200 Subject: [PATCH 34/44] updated license and readme --- LICENSE | 2 +- README.md | 16 ++++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/LICENSE b/LICENSE index 4064ca5..0720e25 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021 Ioannis Kaliakatsos +Copyright (c) 2022 Ioannis Kaliakatsos Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 58a7386..b51f120 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,13 @@ [![CMake Build Matrix](https://github.com/jkalias/functional_vector/actions/workflows/cmake.yml/badge.svg)](https://github.com/jkalias/functional_vector/actions/workflows/cmake.yml) [![GitHub license](https://img.shields.io/github/license/jkalias/functional_vector)](https://github.com/jkalias/functional_vector/blob/main/LICENSE) -# Say hello to functional C++ vectors -A wrapper for C++ std::vector geared towards functional programming and fluent APIs. -The primary focus is readability at the call site (not performance) and eliminating manual management of vector indices. -This is heavily influenced and inspired by C# and Swift. +# Say hello to functional C++ +A wrapper for C++ std::vector and std::set, geared towards functional programming and fluent APIs. +The primary focus of this library is +* readability at the call site ("make it work, make it right, make it fast", in that order) +* elimination of vector index operations +* encapsulation of the iterator madness +* removal of manual for-loops +This project is heavily influenced and inspired by C# and Swift. ## Compilation (Cmake) ### Dependencies @@ -29,7 +33,7 @@ build/tests/unit_tests ``` ### macOS (Makefiles/g++) -Assuming you have installed Homebrew, then you can use the gcc and g++ compilers by doing the following (this example uses version gcc 11) +Assuming you have installed Homebrew, you can then use the gcc and g++ compilers by doing the following (this example uses version gcc 11) ```console cd functional_vector cmake \ @@ -56,7 +60,7 @@ cmake -S . -B build ``` Then open the generated ```functional_vector.sln``` in the ```build``` folder. -## Usage +## Usage (functional_vector) ### zip, map, filter, sort ```c++ #include "functional_vector.h" // instead of From 740e319902b6dacfdc2c1ec68766928edaa4d940 Mon Sep 17 00:00:00 2001 From: jkalias Date: Wed, 13 Jul 2022 22:52:18 +0200 Subject: [PATCH 35/44] Update README.md --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index b51f120..260cdcd 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,14 @@ [![CMake Build Matrix](https://github.com/jkalias/functional_vector/actions/workflows/cmake.yml/badge.svg)](https://github.com/jkalias/functional_vector/actions/workflows/cmake.yml) [![GitHub license](https://img.shields.io/github/license/jkalias/functional_vector)](https://github.com/jkalias/functional_vector/blob/main/LICENSE) # Say hello to functional C++ -A wrapper for C++ std::vector and std::set, geared towards functional programming and fluent APIs. +A wrapper for C++ std::vector and std::set geared towards functional programming and fluent APIs. This project is heavily influenced and inspired by C# and Swift. + The primary focus of this library is -* readability at the call site ("make it work, make it right, make it fast", in that order) +* readability at the call site ("make it work, make it right, make it fast") +* surfacing existing algorithms from the standard library, and lowering the barrier for their extended usage * elimination of vector index operations * encapsulation of the iterator madness * removal of manual for-loops -This project is heavily influenced and inspired by C# and Swift. ## Compilation (Cmake) ### Dependencies From 62e4701e2995a0a6a87aa068c579112ea39e6bf0 Mon Sep 17 00:00:00 2001 From: jkaliak Date: Thu, 14 Jul 2022 00:00:14 +0200 Subject: [PATCH 36/44] introduced fcpp namespace --- include/functional_set.h | 12 ++++++++---- include/functional_vector.h | 12 ++++++++---- include/optional.h | 3 +++ src/CMakeLists.txt | 2 +- tests/CMakeLists.txt | 2 +- tests/functional_set_test.cc | 2 ++ tests/functional_vector_test.cc | 2 ++ tests/optional_test.cc | 2 ++ 8 files changed, 27 insertions(+), 10 deletions(-) diff --git a/include/functional_set.h b/include/functional_set.h index c01ff85..e712708 100644 --- a/include/functional_set.h +++ b/include/functional_set.h @@ -25,6 +25,8 @@ #include #include "optional.h" +namespace fcpp { + template class functional_vector; @@ -150,12 +152,12 @@ class functional_set // outcome: // minimum.has_value() -> true // minimum.value() -> 1 - [[nodiscard]] optional_t min() const { + [[nodiscard]] fcpp::optional_t min() const { const auto& it = std::min_element(begin(), end()); if (it != end()) { return *it; } - return optional_t(); + return fcpp::optional_t(); } // Returns the maximum key in the set, if it's not empty. @@ -170,12 +172,12 @@ class functional_set // outcome: // maximum.has_value() -> true // maximum.value() -> 8 - [[nodiscard]] optional_t max() const { + [[nodiscard]] fcpp::optional_t max() const { const auto& it = std::max_element(begin(), end()); if (it != end()) { return *it; } - return optional_t(); + return fcpp::optional_t(); } // Performs the functional `map` algorithm, in which every element of the resulting set is the @@ -670,3 +672,5 @@ class functional_set return functional_set>(combined_set); } }; + +} diff --git a/include/functional_vector.h b/include/functional_vector.h index 544de18..82a7e31 100644 --- a/include/functional_vector.h +++ b/include/functional_vector.h @@ -30,6 +30,8 @@ #include #endif +namespace fcpp { + template class functional_set; @@ -727,7 +729,7 @@ class functional_vector // index_of_one.value() -> 0 // index_of_one.has_value() -> true // index_of_nine.has_value() -> false - [[nodiscard]] optional_t find_first_index(const T& element) const + [[nodiscard]] fcpp::optional_t find_first_index(const T& element) const { auto const it = std::find(backing_vector_.cbegin(), backing_vector_.cend(), @@ -736,7 +738,7 @@ class functional_vector auto index = std::distance(backing_vector_.cbegin(), it); return index; } - return optional_t(); + return fcpp::optional_t(); } // Returns the last index in which the given element is found in the vector. @@ -752,7 +754,7 @@ class functional_vector // index_of_one.value() -> 8 // index_of_one.has_value() -> true // index_of_nine.has_value() -> false - [[nodiscard]] optional_t find_last_index(const T& element) const + [[nodiscard]] fcpp::optional_t find_last_index(const T& element) const { auto const it = std::find(backing_vector_.crbegin(), backing_vector_.crend(), @@ -761,7 +763,7 @@ class functional_vector auto index = std::distance(it, backing_vector_.crend()) - 1; return index; } - return optional_t(); + return fcpp::optional_t(); } // Returns all indices in which the given element is found in the vector. @@ -1653,3 +1655,5 @@ class functional_vector assert(index <= size() && index >= 0); } }; + +} diff --git a/include/optional.h b/include/optional.h index 59a803d..805d08f 100644 --- a/include/optional.h +++ b/include/optional.h @@ -32,6 +32,8 @@ using optional_t = std::optional; #include #include +namespace fcpp { + // A replacement for std::optional when C++17 is not available template class optional { @@ -97,4 +99,5 @@ class optional { template using optional_t = optional; +} #endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e657fde..82fe24a 100755 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,4 +1,4 @@ -set (LIBNAME functional_cpp) +set (LIBNAME fcpp) # Properties->C/C++->General->Additional Include Directories include_directories ("../include") diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 78514b3..9719af1 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -16,7 +16,7 @@ file (GLOB TEST_SOURCES add_executable (${EXENAME} ${TEST_SOURCES}) # Properties->Linker->Input->Additional Dependencies -target_link_libraries(${EXENAME} PUBLIC functional_cpp gtest_main) +target_link_libraries(${EXENAME} PUBLIC fcpp gtest_main) # Creates a folder "executables" and adds target project under it set_property(TARGET ${EXENAME} PROPERTY FOLDER "executables") diff --git a/tests/functional_set_test.cc b/tests/functional_set_test.cc index 6add909..cd9290e 100644 --- a/tests/functional_set_test.cc +++ b/tests/functional_set_test.cc @@ -26,6 +26,8 @@ #include "functional_vector.h" #include "test_types.h" +using namespace fcpp; + template void debug(functional_set& set) { diff --git a/tests/functional_vector_test.cc b/tests/functional_vector_test.cc index 8747854..b70b6b9 100644 --- a/tests/functional_vector_test.cc +++ b/tests/functional_vector_test.cc @@ -28,6 +28,8 @@ #include "test_types.h" #include "warnings.h" +using namespace fcpp; + template void debug(const functional_vector& vec) { diff --git a/tests/optional_test.cc b/tests/optional_test.cc index 699f1d1..f2d2b7c 100644 --- a/tests/optional_test.cc +++ b/tests/optional_test.cc @@ -23,6 +23,8 @@ #include #include "optional.h" +using namespace fcpp; + TEST(OptionalTest, InvalidTest) { const optional_t index; EXPECT_FALSE(index.has_value()); From 240c1b8d54379efc5c360972266fc12b970dcd14 Mon Sep 17 00:00:00 2001 From: jkalias Date: Thu, 14 Jul 2022 00:11:43 +0200 Subject: [PATCH 37/44] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 260cdcd..4c9bdf0 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -[![CMake Build Matrix](https://github.com/jkalias/functional_vector/actions/workflows/cmake.yml/badge.svg)](https://github.com/jkalias/functional_vector/actions/workflows/cmake.yml) -[![GitHub license](https://img.shields.io/github/license/jkalias/functional_vector)](https://github.com/jkalias/functional_vector/blob/main/LICENSE) +[![CMake Build Matrix](https://github.com/jkalias/functional_cpp/actions/workflows/cmake.yml/badge.svg)](https://github.com/jkalias/functional_cpp/actions/workflows/cmake.yml) +[![GitHub license](https://img.shields.io/github/license/jkalias/functional_cpp)](https://github.com/jkalias/functional_cpp/blob/main/LICENSE) # Say hello to functional C++ A wrapper for C++ std::vector and std::set geared towards functional programming and fluent APIs. This project is heavily influenced and inspired by C# and Swift. From 08a44b0f9a860e9259e54512eb00c53508a21bb3 Mon Sep 17 00:00:00 2001 From: jkaliak Date: Thu, 14 Jul 2022 00:26:49 +0200 Subject: [PATCH 38/44] renamed vector and set (along with their tests), and updated the documentation to use functional_cpp and fcpp --- CMakeLists.txt | 2 +- README.md | 68 +- include/{functional_set.h => set.h} | 88 +-- include/{functional_vector.h => vector.h} | 182 ++--- tests/{functional_set_test.cc => set_test.cc} | 306 ++++---- ...nctional_vector_test.cc => vector_test.cc} | 712 +++++++++--------- 6 files changed, 679 insertions(+), 679 deletions(-) rename include/{functional_set.h => set.h} (88%) rename include/{functional_vector.h => vector.h} (90%) rename tests/{functional_set_test.cc => set_test.cc} (50%) rename tests/{functional_vector_test.cc => vector_test.cc} (54%) diff --git a/CMakeLists.txt b/CMakeLists.txt index d0c189a..980f4e7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.14) -project(functional_vector VERSION 0.9) +project(functional_cpp VERSION 1.0) # GoogleTest requires at least C++11 if(NOT "${CMAKE_CXX_STANDARD}") diff --git a/README.md b/README.md index 4c9bdf0..3b6adc4 100644 --- a/README.md +++ b/README.md @@ -20,14 +20,14 @@ The primary focus of this library is An out-of-source build strategy is used. All following examples assume an output build folder named ```build```. If no additional argument is passed to CMake, C++11 is used. Otherwise, you can pass ```-DCMAKE_CXX_STANDARD=17``` and it will use C++17 for example. ### macOS (Xcode) ```console -cd functional_vector +cd functional_cpp cmake -S . -B build -G Xcode ``` -Then open the generated ```functional_vector.xcodeproj``` in the ```build``` folder. +Then open the generated ```functional_cpp.xcodeproj``` in the ```build``` folder. ### macOS (Makefiles/clang) ```console -cd functional_vector +cd functional_cpp cmake -S . -B build cmake --build build build/tests/unit_tests @@ -36,7 +36,7 @@ build/tests/unit_tests ### macOS (Makefiles/g++) Assuming you have installed Homebrew, you can then use the gcc and g++ compilers by doing the following (this example uses version gcc 11) ```console -cd functional_vector +cd functional_cpp cmake \ -S . \ -B build \ @@ -48,7 +48,7 @@ build/tests/unit_tests ### Linux (Makefiles) ```console -cd functional_vector +cd functional_cpp cmake -S . -B build cmake --build build build/tests/unit_tests @@ -56,15 +56,15 @@ build/tests/unit_tests ### Windows (Visual Studio) ```console -cd functional_vector +cd functional_cpp cmake -S . -B build ``` -Then open the generated ```functional_vector.sln``` in the ```build``` folder. +Then open the generated ```functional_cpp.sln``` in the ```build``` folder. -## Usage (functional_vector) +## Usage (fcpp::vector) ### zip, map, filter, sort ```c++ -#include "functional_vector.h" // instead of +#include "vector.h" // instead of struct person { person(int age, std::string name) @@ -77,10 +77,10 @@ struct person { // ... // the employees' ages -const functional_vector ages({32, 45, 37, 23}); +const fcpp::vector ages({32, 45, 37, 23}); // the employees' names -const functional_vector names({"Jake", "Anna", "Kate", "Bob"}); +const fcpp::vector names({"Jake", "Anna", "Kate", "Bob"}); const auto employees_below_40 = ages // zip two vectors for simultaneous processing @@ -113,9 +113,9 @@ employees_below_40.for_each([](const auto& person) { ``` ### index search ```c++ -#include "functional_vector.h" // instead of +#include "vector.h" // instead of -const functional_vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); +const fcpp::vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); const auto first_index_of_one = numbers.find_first_index(1); // returns 0 @@ -135,63 +135,63 @@ index_of_nine.has_value(); ### remove, insert ```c++ -#include "functional_vector.h" // instead of +#include "vector.h" // instead of #include "index_range.h" -functional_vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); +fcpp::vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); -// numbers -> functional_vector({1, 4, 2, 5, 3, 1, 7, 1}); +// numbers -> fcpp::vector({1, 4, 2, 5, 3, 1, 7, 1}); numbers.remove_at(4); -// numbers -> functional_vector({4, 2, 5, 3, 1, 7, 1}); +// numbers -> fcpp::vector({4, 2, 5, 3, 1, 7, 1}); numbers.remove_front(); -// numbers -> functional_vector({4, 2, 5, 3, 1, 7}); +// numbers -> fcpp::vector({4, 2, 5, 3, 1, 7}); numbers.remove_back(); -// numbers -> functional_vector({4, 2, 7}); +// numbers -> fcpp::vector({4, 2, 7}); numbers.remove_range(index_range::start_count(2, 3)); -// numbers -> functional_vector({4, 8, 2, 7}); +// numbers -> fcpp::vector({4, 8, 2, 7}); numbers.insert_at(1, 8); -// numbers -> functional_vector({-10, 4, 8, 2, 7}); +// numbers -> fcpp::vector({-10, 4, 8, 2, 7}); numbers.insert_front(-10); -// numbers -> functional_vector({-10, 4, 8, 2, 7, 9}); +// numbers -> fcpp::vector({-10, 4, 8, 2, 7, 9}); numbers.insert_back(9); -// numbers -> functional_vector({-10, 4, 8, 3, -2, 5, 2, 7, 9}); +// numbers -> fcpp::vector({-10, 4, 8, 3, -2, 5, 2, 7, 9}); numbers.insert_at(3, std::vector({3, -2, 5})); -// numbers -> functional_vector({4, -6, 7, -10, 4, 8, 3, -2, 5, 2, 7, 9}); -numbers.insert_front(functional_vector({4, -6, 7})); +// numbers -> fcpp::vector({4, -6, 7, -10, 4, 8, 3, -2, 5, 2, 7, 9}); +numbers.insert_front(fcpp::vector({4, -6, 7})); -// numbers -> functional_vector({4, -6, 7, -10, 4, 8, 3, -2, 5, 2, 7, 9, 7, 3}); +// numbers -> fcpp::vector({4, -6, 7, -10, 4, 8, 3, -2, 5, 2, 7, 9, 7, 3}); numbers.insert_back(std::initializer_list({7, 3})); ``` ### size/capacity, reserve/resize ```c++ -#include "functional_vector.h" // instead of +#include "vector.h" // instead of // numbers.capacity() = 9 // numbers.size() = 9 -functional_vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); +fcpp::vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); -// numbers -> functional_vector({1, 4, 2, 5, 8}); +// numbers -> fcpp::vector({1, 4, 2, 5, 8}); // numbers.capacity() = 9 // numbers.size() = 5 numbers.resize(5); -// numbers -> functional_vector({1, 4, 2, 5, 8, 0, 0}); +// numbers -> fcpp::vector({1, 4, 2, 5, 8, 0, 0}); // numbers.capacity() = 9 // numbers.size() = 7 numbers.resize(7); // empty_numbers.capacity() = 0 // empty_numbers.size() = 0 -functional_vector empty_numbers; +fcpp::vector empty_numbers; // empty_numbers.capacity() = 5 // empty_numbers.size() = 0 @@ -200,9 +200,9 @@ empty_numbers.reserve(5); ### all_of, any_of, none_of ```c++ -#include "functional_vector.h" // instead of +#include "vector.h" // instead of -functional_vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); +fcpp::vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); // returns true numbers.all_of([](const auto &number) { @@ -238,7 +238,7 @@ numbers.none_of([](const auto &number) { ### Parallel algorithms Since C++17 several STL algorithms can be executed in parallel. -clang on macOS does not yet fully support the parallel execution model, however on Windows and Linux, a `functional_vector` supports the following parallel algorithms +clang on macOS does not yet fully support the parallel execution model, however on Windows and Linux, an `fcpp::vector` supports the following parallel algorithms ```c++ for_each_parallel map_parallel diff --git a/include/functional_set.h b/include/set.h similarity index 88% rename from include/functional_set.h rename to include/set.h index e712708..50c14bd 100644 --- a/include/functional_set.h +++ b/include/set.h @@ -28,7 +28,7 @@ namespace fcpp { template -class functional_vector; +class vector; // A lightweight wrapper around std::set, enabling fluent and functional // programming on the set itself, rather than using the more procedural style @@ -37,30 +37,30 @@ class functional_vector; // Member functions can be mutating (eg. my_set.insert()) or // non-mutating (eg. my_vector.inserting()) enforcing thread safety if needed template > -class functional_set +class set { public: - functional_set() + set() : backing_set_() { } - explicit functional_set(std::set set) + explicit set(std::set set) : backing_set_(std::move(set)) { } - explicit functional_set(const std::vector& vector) + explicit set(const std::vector& vector) : backing_set_(vector.begin(), vector.end()) { } - explicit functional_set(const functional_vector& vector) + explicit set(const vector& vector) : backing_set_(vector.begin(), vector.end()) { } - explicit functional_set(const std::initializer_list& list) + explicit set(const std::initializer_list& list) : backing_set_(list.begin(), list.end()) { } @@ -76,18 +76,18 @@ class functional_set // // outcome: // diff -> functional_set({1, 3, 8}) - [[nodiscard]] functional_set difference_with(const functional_set& other) const { + [[nodiscard]] set difference_with(const set& other) const { std::set diff; std::set_difference(begin(), end(), other.begin(), other.end(), std::inserter(diff, diff.begin())); - return functional_set(diff); + return set(diff); } - [[nodiscard]] functional_set difference_with(const std::set& other) const { - return difference_with(functional_set(other)); + [[nodiscard]] set difference_with(const std::set& other) const { + return difference_with(set(other)); } // Returns the set of elements which belong either to the current or the other set. @@ -101,18 +101,18 @@ class functional_set // // outcome: // combined -> functional_set({1, 2, 3, 5, 7, 8, 10, 15, 17}) - [[nodiscard]] functional_set union_with(const functional_set& other) const { + [[nodiscard]] set union_with(const set& other) const { std::set combined; std::set_union(begin(), end(), other.begin(), other.end(), std::inserter(combined, combined.begin())); - return functional_set(combined); + return set(combined); } - [[nodiscard]] functional_set union_with(const std::set& other) const { - return union_with(functional_set(other)); + [[nodiscard]] set union_with(const std::set& other) const { + return union_with(set(other)); } // Returns the set of elements which belong to both the current and the other set. @@ -126,18 +126,18 @@ class functional_set // // outcome: // combined -> functional_set({2, 5, 7, 10}) - [[nodiscard]] functional_set intersect_with(const functional_set& other) const { + [[nodiscard]] set intersect_with(const set& other) const { std::set intersection; std::set_intersection(begin(), end(), other.begin(), other.end(), std::inserter(intersection, intersection.begin())); - return functional_set(intersection); + return set(intersection); } - [[nodiscard]] functional_set intersect_with(const std::set& other) const { - return intersect_with(functional_set(other)); + [[nodiscard]] set intersect_with(const std::set& other) const { + return intersect_with(set(other)); } // Returns the minimum key in the set, if it's not empty. @@ -203,13 +203,13 @@ class functional_set #else template , typename Transform> #endif - functional_set map(Transform && transform) const + set map(Transform && transform) const { std::set transformed_set; for (const auto& key: backing_set_) { transformed_set.insert(transform(key)); } - return functional_set(transformed_set); + return set(transformed_set); } // Returns true if all keys match the predicate (return true) @@ -316,7 +316,7 @@ class functional_set #else template #endif - functional_set& filter(Filter && predicate_to_keep) + set& filter(Filter && predicate_to_keep) { std::set copy; auto it = begin(); @@ -346,7 +346,7 @@ class functional_set #else template #endif - functional_set filtered(Filter && predicate_to_keep) const + set filtered(Filter && predicate_to_keep) const { std::set copy; auto it = begin(); @@ -355,7 +355,7 @@ class functional_set copy.insert(*it); } } - return functional_set(copy); + return set(copy); } #ifdef CPP17_AVAILABLE @@ -385,7 +385,7 @@ class functional_set // std::pair(63, "Philipp"), // }) template - [[nodiscard]] functional_set> zip(const functional_set& set) const + [[nodiscard]] set> zip(const set& set) const { #ifdef CPP17_AVAILABLE return zip_impl(set.begin(), set.end()); @@ -398,16 +398,16 @@ class functional_set // The number of keys must match the set's size. // For more details, see the zip function which accepts a functional_set as input. template - [[nodiscard]] functional_set> zip(const std::set& set) const + [[nodiscard]] set> zip(const std::set& set) const { - return zip(functional_set(set)); + return zip(fcpp::set(set)); } // Performs the functional `zip` algorithm by using the unique values of the vector. // The number of uniques vector values must match the set's size. // For more details, see the zip function which accepts a functional_set as input. template - [[nodiscard]] functional_set> zip(const functional_vector& vector) const + [[nodiscard]] set> zip(const vector& vector) const { const auto distinct_values = vector.distinct(); return zip(distinct_values); @@ -417,9 +417,9 @@ class functional_set // The number of uniques vector values must match the set's size. // For more details, see the zip function which accepts a functional_set as input. template - [[nodiscard]] functional_set> zip(const std::vector& vector) const + [[nodiscard]] set> zip(const std::vector& vector) const { - return zip(functional_vector(vector)); + return zip(fcpp::vector(vector)); } // Executes the given operation for each key of the set. @@ -429,7 +429,7 @@ class functional_set #else template #endif - const functional_set& for_each(Callable && operation) const + const set& for_each(Callable && operation) const { std::for_each(begin(), end(), @@ -445,7 +445,7 @@ class functional_set // // outcome: // numbers -> functional_set({1, 2}) - functional_set& remove(const TKey& element) + set& remove(const TKey& element) { backing_set_.erase(element); return *this; @@ -460,11 +460,11 @@ class functional_set // outcome: // less_numbers -> functional_set({1, 2}) // numbers -> functional_set({1, 2, 4}) - [[nodiscard]] functional_set removing(const TKey& element) const + [[nodiscard]] set removing(const TKey& element) const { auto copy(backing_set_); copy.erase(element); - return functional_set(copy); + return set(copy); } // Inserts an element in the set, if it does not already exist, potentially changing the set's contents (mutating) @@ -475,7 +475,7 @@ class functional_set // // outcome: // numbers -> functional_set({1, 2, 4, 18}) - functional_set& insert(const TKey& element) + set& insert(const TKey& element) { backing_set_.insert(element); return *this; @@ -490,11 +490,11 @@ class functional_set // outcome: // augmented_numbers -> functional_set({1, 2, 4, 18}) // numbers -> functional_set({1, 2, 4}) - [[nodiscard]] functional_set inserting(const TKey& element) const + [[nodiscard]] set inserting(const TKey& element) const { auto copy(backing_set_); copy.insert(element); - return functional_set(copy); + return set(copy); } // Removes all keys from the set (mutating) @@ -505,7 +505,7 @@ class functional_set // // outcome: // numbers -> functional_set({}) - functional_set& clear() + set& clear() { backing_set_.clear(); return *this; @@ -520,9 +520,9 @@ class functional_set // outcome: // cleared_numbers -> functional_set({}) // numbers -> functional_set numbers({1, 4, 2}) - [[nodiscard]] functional_set clearing() const + [[nodiscard]] set clearing() const { - return functional_set(); + return set(); } // Returns true if the key is present in the set, otherwise false @@ -609,7 +609,7 @@ class functional_set } // Returns true if both instances have equal sizes and the corresponding elements (keys) are equal - bool operator ==(const functional_set& rhs) const + bool operator ==(const set& rhs) const { #ifdef CPP17_AVAILABLE return std::equal(begin(), @@ -636,7 +636,7 @@ class functional_set } // Returns false if either the sizes are not equal or at least one corresponding element (key) is not equal - bool operator !=(const functional_set& rhs) const + bool operator !=(const set& rhs) const { return !((*this) == rhs); } @@ -657,7 +657,7 @@ class functional_set using UKey = deref_type; #else template - [[nodiscard]] functional_set> zip_impl(const typename std::set::const_iterator& set_begin, + [[nodiscard]] set> zip_impl(const typename std::set::const_iterator& set_begin, const typename std::set::const_iterator& set_end) const { #endif @@ -669,7 +669,7 @@ class functional_set for (; it1 != end() && it2 != set_end; it1++, it2++) { combined_set.insert({*it1, *it2}); } - return functional_set>(combined_set); + return set>(combined_set); } }; diff --git a/include/functional_vector.h b/include/vector.h similarity index 90% rename from include/functional_vector.h rename to include/vector.h index 82a7e31..7925acb 100644 --- a/include/functional_vector.h +++ b/include/vector.h @@ -33,7 +33,7 @@ namespace fcpp { template -class functional_set; +class set; // A lightweight wrapper around std::vector, enabling fluent and functional // programming on the vector itself, rather than using the more procedural style @@ -42,25 +42,25 @@ class functional_set; // Member functions can be mutating (eg. my_vector.reverse()) or // non-mutating (eg. my_vector.reversed()) enforcing thread safety if needed template -class functional_vector +class vector { public: - functional_vector() + vector() : backing_vector_() { } - explicit functional_vector(const std::vector& vector) + explicit vector(const std::vector& vector) : backing_vector_(vector) { } - explicit functional_vector(std::vector&& vector) + explicit vector(std::vector&& vector) : backing_vector_(std::move(vector)) { } - explicit functional_vector(std::initializer_list list) + explicit vector(std::initializer_list list) : backing_vector_(std::move(list)) { } @@ -72,7 +72,7 @@ class functional_vector // // outcome: // filled_vector -> functional_vector({ "John", "John", "John" }) - explicit functional_vector(size_t count, const T& element) + explicit vector(size_t count, const T& element) : backing_vector_(count, element) { } @@ -100,7 +100,7 @@ class functional_vector #else template #endif - functional_vector map(Transform && transform) const + vector map(Transform && transform) const { std::vector transformed_vector; transformed_vector.reserve(backing_vector_.size()); @@ -108,7 +108,7 @@ class functional_vector backing_vector_.end(), std::back_inserter(transformed_vector), std::forward(transform)); - return functional_vector(transformed_vector); + return vector(transformed_vector); } #ifdef PARALLEL_ALGORITHM_AVAILABLE @@ -271,7 +271,7 @@ class functional_vector #else template #endif - functional_vector& filter(Filter && predicate_to_keep) + vector& filter(Filter && predicate_to_keep) { backing_vector_.erase(std::remove_if(backing_vector_.begin(), backing_vector_.end(), @@ -323,7 +323,7 @@ class functional_vector #else template #endif - functional_vector filtered(Callable && predicate_to_keep) const + vector filtered(Callable && predicate_to_keep) const { std::vector filtered_vector; filtered_vector.reserve(backing_vector_.size()); @@ -331,7 +331,7 @@ class functional_vector backing_vector_.end(), std::back_inserter(filtered_vector), std::forward(predicate_to_keep)); - return functional_vector(filtered_vector); + return vector(filtered_vector); } #ifdef PARALLEL_ALGORITHM_AVAILABLE @@ -366,7 +366,7 @@ class functional_vector // // outcome: // numbers_vector -> functional_vector({ -4, 9, -1, 2, -5, 3, 1 }) - functional_vector& reverse() + vector& reverse() { std::reverse(backing_vector_.begin(), backing_vector_.end()); return *this; @@ -381,10 +381,10 @@ class functional_vector // outcome: // input_vector -> functional_vector({ 1, 3, -5, 2, -1, 9, -4 }); // reversed_vector -> functional_vector({ -4, 9, -1, 2, -5, 3, 1 }) - [[nodiscard]] functional_vector reversed() const + [[nodiscard]] vector reversed() const { std::vector reversed_vector(backing_vector_.crbegin(), backing_vector_.crend()); - return functional_vector(std::move(reversed_vector)); + return vector(std::move(reversed_vector)); } #ifdef CPP17_AVAILABLE @@ -424,7 +424,7 @@ class functional_vector // zipped_vector.insert_back(tuple); // } template - [[nodiscard]] functional_vector> zip(const functional_vector& vector) const + [[nodiscard]] vector> zip(const vector& vector) const { #ifdef CPP17_AVAILABLE return zip_impl(vector.begin(), vector.end()); @@ -460,7 +460,7 @@ class functional_vector // zipped_vector.insert_back(tuple); // } template - [[nodiscard]] functional_vector> zip(const std::vector& vector) const + [[nodiscard]] vector> zip(const std::vector& vector) const { #ifdef CPP17_AVAILABLE return zip_impl(vector.cbegin(), vector.cend()); @@ -492,7 +492,7 @@ class functional_vector // zipped_vector.insert_back(tuple); // } template - [[nodiscard]] functional_vector> zip(const std::initializer_list& list) const + [[nodiscard]] vector> zip(const std::initializer_list& list) const { #ifdef CPP17_AVAILABLE return zip_impl(list.begin(), list.end()); @@ -527,7 +527,7 @@ class functional_vector #else template #endif - functional_vector& sort(Sortable && comparison_predicate) + vector& sort(Sortable && comparison_predicate) { std::sort(backing_vector_.begin(), backing_vector_.end(), @@ -557,7 +557,7 @@ class functional_vector // // outcome: // numbers -> functional_vector({-4, 1, 3, 9}); - functional_vector& sort_ascending() + vector& sort_ascending() { return sort(std::less_equal()); } @@ -579,7 +579,7 @@ class functional_vector // // outcome: // numbers -> functional_vector({9, 3, 1, -4}); - functional_vector& sort_descending() + vector& sort_descending() { return sort(std::greater_equal()); } @@ -619,13 +619,13 @@ class functional_vector #else template #endif - functional_vector sorted(Sortable && comparison_predicate) const + vector sorted(Sortable && comparison_predicate) const { auto sorted_vector(backing_vector_); std::sort(sorted_vector.begin(), sorted_vector.end(), std::forward(comparison_predicate)); - return functional_vector(sorted_vector); + return vector(sorted_vector); } #ifdef PARALLEL_ALGORITHM_AVAILABLE @@ -651,7 +651,7 @@ class functional_vector // // outcome: // sorted_numbers -> functional_vector({-4, 1, 3, 9}); - [[nodiscard]] functional_vector sorted_ascending() const + [[nodiscard]] vector sorted_ascending() const { return sorted(std::less_equal()); } @@ -673,7 +673,7 @@ class functional_vector // // outcome: // sorted_numbers -> functional_vector({9, 3, 1, -4}); - [[nodiscard]] functional_vector sorted_descending() const + [[nodiscard]] vector sorted_descending() const { return sorted(std::greater_equal()); } @@ -694,7 +694,7 @@ class functional_vector #else template #endif - const functional_vector& for_each(Callable && operation) const + const vector& for_each(Callable && operation) const { std::for_each(backing_vector_.cbegin(), backing_vector_.cend(), @@ -799,7 +799,7 @@ class functional_vector // // outcome: // numbers -> functional_vector({1, 4, 2, 5, 3, 1, 7, 1}); - functional_vector& remove_at(int index) + vector& remove_at(int index) { assert_smaller_size(index); backing_vector_.erase(begin() + index); @@ -814,12 +814,12 @@ class functional_vector // // outcome: // shorter_vector -> functional_vector({1, 4, 2, 5, 3, 1, 7, 1}); - [[nodiscard]] functional_vector removing_at(int index) const + [[nodiscard]] vector removing_at(int index) const { assert_smaller_size(index); auto copy(backing_vector_); copy.erase(copy.begin() + index); - return functional_vector(copy); + return vector(copy); } // Removes the last element, if present (mutating) @@ -830,7 +830,7 @@ class functional_vector // // outcome: // numbers -> functional_vector({1, 4, 2, 5, 8, 3, 1, 7}); - functional_vector& remove_back() + vector& remove_back() { backing_vector_.pop_back(); return *this; @@ -844,11 +844,11 @@ class functional_vector // // outcome: // shorter_vector -> functional_vector({1, 4, 2, 5, 8, 3, 1, 7}); - [[nodiscard]] functional_vector removing_back() const + [[nodiscard]] vector removing_back() const { auto copy(backing_vector_); copy.pop_back(); - return functional_vector(copy); + return vector(copy); } // Removes the first element, if present (mutating) @@ -859,7 +859,7 @@ class functional_vector // // outcome: // numbers -> functional_vector({4, 2, 5, 8, 3, 1, 7, 1}); - functional_vector& remove_front() + vector& remove_front() { if (size() == 0) { @@ -876,7 +876,7 @@ class functional_vector // // outcome: // shorter_numbers -> functional_vector({4, 2, 5, 8, 3, 1, 7, 1}); - [[nodiscard]] functional_vector removing_front() const + [[nodiscard]] vector removing_front() const { if (size() == 0) { @@ -893,7 +893,7 @@ class functional_vector // // outcome: // numbers -> functional_vector({ 1, 4, 2, 7, 1 }) - functional_vector& remove_range(index_range range) + vector& remove_range(index_range range) { if (!range.is_valid || size() < range.end + 1) { @@ -912,7 +912,7 @@ class functional_vector // // outcome: // shorter_vector -> functional_vector({ 1, 4, 3, 1, 7, 1 }) - [[nodiscard]] functional_vector removing_range(index_range range) const + [[nodiscard]] vector removing_range(index_range range) const { if (!range.is_valid || size() < range.end + 1) { @@ -921,7 +921,7 @@ class functional_vector auto shorter_vector(backing_vector_); shorter_vector.erase(shorter_vector.begin() + range.start, shorter_vector.begin() + range.start + range.count); - return functional_vector(shorter_vector); + return vector(shorter_vector); } // Inserts an element at the given index, therefore changing the vector's contents (mutating) @@ -932,7 +932,7 @@ class functional_vector // // outcome: // numbers -> functional_vector({1, 4, 2, 18, 5, 8, 3, 1, 7, 1}); - functional_vector& insert_at(int index, const T& element) + vector& insert_at(int index, const T& element) { assert_smaller_or_equal_size(index); backing_vector_.insert(begin() + index, element); @@ -947,12 +947,12 @@ class functional_vector // // outcome: // augmented_numbers -> functional_vector({1, 4, 2, 18, 5, 8, 3, 1, 7, 1}); - [[nodiscard]] functional_vector inserting_at(int index, const T& element) const + [[nodiscard]] vector inserting_at(int index, const T& element) const { assert_smaller_or_equal_size(index); auto copy(backing_vector_); copy.insert(copy.begin() + index, element); - return functional_vector(copy); + return vector(copy); } // Inserts a range of elements starting at the given index, therefore changing the vector's contents (mutating) @@ -964,7 +964,7 @@ class functional_vector // // outcome: // numbers -> functional_vector({1, 4, 2, 9, -5, 6, 5, 8, 3, 1, 7, 1}); - functional_vector& insert_at(int index, const functional_vector& vector) + vector& insert_at(int index, const vector& vector) { return insert_at_impl(index, vector.begin(), vector.end()); } @@ -978,7 +978,7 @@ class functional_vector // // outcome: // augmented_numbers -> functional_vector({1, 4, 2, 9, -5, 6, 5, 8, 3, 1, 7, 1}); - [[nodiscard]] functional_vector inserting_at(int index, const functional_vector& vector) const + [[nodiscard]] vector inserting_at(int index, const vector& vector) const { return inserting_at_impl(index, vector.begin(), vector.end()); } @@ -992,7 +992,7 @@ class functional_vector // // outcome: // numbers -> functional_vector({1, 4, 2, 9, -5, 6, 5, 8, 3, 1, 7, 1}); - functional_vector& insert_at(int index, const std::vector& vector) + vector& insert_at(int index, const std::vector& vector) { return insert_at_impl(index, vector.cbegin(), vector.cend()); } @@ -1006,7 +1006,7 @@ class functional_vector // // outcome: // augmented_numbers -> functional_vector({1, 4, 2, 9, -5, 6, 5, 8, 3, 1, 7, 1}); - [[nodiscard]] functional_vector inserting_at(int index, const std::vector& vector) const + [[nodiscard]] vector inserting_at(int index, const std::vector& vector) const { return inserting_at_impl(index, vector.cbegin(), vector.cend()); } @@ -1020,7 +1020,7 @@ class functional_vector // // outcome: // numbers -> functional_vector({1, 4, 2, 9, -5, 6, 5, 8, 3, 1, 7, 1}); - functional_vector& insert_at(int index, std::initializer_list list) + vector& insert_at(int index, std::initializer_list list) { return insert_at(index, std::vector(std::move(list))); } @@ -1034,7 +1034,7 @@ class functional_vector // // outcome: // augmented_numbers -> functional_vector({1, 4, 2, 9, -5, 6, 5, 8, 3, 1, 7, 1}); - [[nodiscard]] functional_vector inserting_at(int index, std::initializer_list list) const + [[nodiscard]] vector inserting_at(int index, std::initializer_list list) const { return inserting_at(index, std::vector(std::move(list))); } @@ -1047,7 +1047,7 @@ class functional_vector // // outcome: // numbers -> functional_vector({1, 4, 2, 5, 8, 3, 1, 7, 1, 18}); - functional_vector& insert_back(T value) + vector& insert_back(T value) { backing_vector_.push_back(value); return *this; @@ -1061,7 +1061,7 @@ class functional_vector // // outcome: // numbers -> functional_vector({18, 1, 4, 2, 5, 8, 3, 1, 7, 1}); - functional_vector& insert_front(T value) + vector& insert_front(T value) { return insert_at(0, value); } @@ -1074,11 +1074,11 @@ class functional_vector // // outcome: // augmented_numbers -> functional_vector({1, 4, 2, 5, 8, 3, 1, 7, 1, 18}); - [[nodiscard]] functional_vector inserting_back(T value) const + [[nodiscard]] vector inserting_back(T value) const { auto augmented_vector(backing_vector_); augmented_vector.push_back(value); - return functional_vector(augmented_vector); + return vector(augmented_vector); } // Makes a copy of the vector, inserts value at the beginning of the copy and returns the copy (non-mutating) @@ -1089,7 +1089,7 @@ class functional_vector // // outcome: // augmented_numbers -> functional_vector({18, 1, 4, 2, 5, 8, 3, 1, 7, 1}); - [[nodiscard]] functional_vector inserting_front(T value) const + [[nodiscard]] vector inserting_front(T value) const { return inserting_at(0, value); } @@ -1102,7 +1102,7 @@ class functional_vector // // outcome: // numbers -> functional_vector numbers({ 4, 5, 6, 1, 2, 3 }); - functional_vector& insert_back(const functional_vector& vector) + vector& insert_back(const vector& vector) { return insert_back_range_impl(vector.begin(), vector.end()); } @@ -1115,7 +1115,7 @@ class functional_vector // // outcome: // numbers -> functional_vector numbers({ 1, 2, 3, 4, 5, 6 }); - functional_vector& insert_front(const functional_vector& vector) + vector& insert_front(const vector& vector) { return insert_front_range_impl(vector.begin(), vector.end()); } @@ -1128,7 +1128,7 @@ class functional_vector // // outcome: // augmented_numbers -> functional_vector numbers({ 4, 5, 6, 1, 2, 3 }); - [[nodiscard]] functional_vector inserting_back(const functional_vector& vector) const + [[nodiscard]] vector inserting_back(const vector& vector) const { return inserting_back_range_impl(vector.begin(), vector.end()); } @@ -1141,7 +1141,7 @@ class functional_vector // // outcome: // augmented_numbers -> functional_vector numbers({ 1, 2, 3, 4, 5, 6 }); - [[nodiscard]] functional_vector inserting_front(const functional_vector& vector) const + [[nodiscard]] vector inserting_front(const vector& vector) const { return inserting_front_range_impl(vector.begin(), vector.end()); } @@ -1154,7 +1154,7 @@ class functional_vector // // outcome: // numbers -> functional_vector numbers({ 4, 5, 6, 1, 2, 3 }); - functional_vector& insert_back(const std::vector& vector) + vector& insert_back(const std::vector& vector) { return insert_back_range_impl(vector.cbegin(), vector.cend()); } @@ -1167,7 +1167,7 @@ class functional_vector // // outcome: // numbers -> functional_vector numbers({ 1, 2, 3, 4, 5, 6 }); - functional_vector& insert_front(const std::vector& vector) + vector& insert_front(const std::vector& vector) { return insert_front_range_impl(vector.cbegin(), vector.cend()); } @@ -1180,7 +1180,7 @@ class functional_vector // // outcome: // augmented_numbers -> functional_vector numbers({ 4, 5, 6, 1, 2, 3 }); - [[nodiscard]] functional_vector inserting_back(const std::vector& vector) const + [[nodiscard]] vector inserting_back(const std::vector& vector) const { return inserting_back_range_impl(vector.cbegin(), vector.cend()); } @@ -1193,7 +1193,7 @@ class functional_vector // // outcome: // augmented_numbers -> functional_vector numbers({ 1, 2, 3, 4, 5, 6 }); - [[nodiscard]] functional_vector inserting_front(const std::vector& vector) const + [[nodiscard]] vector inserting_front(const std::vector& vector) const { return inserting_front_range_impl(vector.cbegin(), vector.cend()); } @@ -1206,7 +1206,7 @@ class functional_vector // // outcome: // numbers -> functional_vector numbers({ 4, 5, 6, 1, 2, 3 }); - functional_vector& insert_back(const std::initializer_list& list) + vector& insert_back(const std::initializer_list& list) { return insert_back(std::vector(list)); } @@ -1219,7 +1219,7 @@ class functional_vector // // outcome: // numbers -> functional_vector numbers({ 1, 2, 3, 4, 5, 6 }); - functional_vector& insert_front(const std::initializer_list& list) + vector& insert_front(const std::initializer_list& list) { return insert_front(std::vector(list)); } @@ -1232,7 +1232,7 @@ class functional_vector // // outcome: // augmented_numbers -> functional_vector numbers({ 4, 5, 6, 1, 2, 3 }); - [[nodiscard]] functional_vector inserting_back(const std::initializer_list& list) const + [[nodiscard]] vector inserting_back(const std::initializer_list& list) const { return inserting_back(std::vector(list)); } @@ -1245,7 +1245,7 @@ class functional_vector // // outcome: // augmented_numbers -> functional_vector numbers({ 1, 2, 3, 4, 5, 6 }); - [[nodiscard]] functional_vector inserting_front(const std::initializer_list& list) const + [[nodiscard]] vector inserting_front(const std::initializer_list& list) const { return inserting_front(std::vector(list)); } @@ -1258,7 +1258,7 @@ class functional_vector // // outcome: // numbers -> functional_vector({ 1, 4, 2, 5, 9, -10, 8, 7, 1 }) - functional_vector& replace_range_at(int index, const functional_vector& vector) + vector& replace_range_at(int index, const vector& vector) { return replace_range_at_imp(index, vector.begin(), vector.end()); } @@ -1271,7 +1271,7 @@ class functional_vector // // outcome: // numbers -> functional_vector({ 1, 4, 2, 5, 9, -10, 8, 7, 1 }) - functional_vector& replace_range_at(int index, const std::vector& vector) + vector& replace_range_at(int index, const std::vector& vector) { return replace_range_at_imp(index, vector.cbegin(), vector.cend()); } @@ -1284,7 +1284,7 @@ class functional_vector // // outcome: // numbers -> functional_vector({ 1, 4, 2, 5, 9, -10, 8, 7, 1 }) - functional_vector& replace_range_at(int index, const std::initializer_list& list) + vector& replace_range_at(int index, const std::initializer_list& list) { return replace_range_at(index, std::vector(list)); } @@ -1297,7 +1297,7 @@ class functional_vector // // outcome: // replaced_numbers -> functional_vector({ 1, 4, 2, 5, 9, -10, 8, 7, 1 }) - [[nodiscard]] functional_vector replacing_range_at(int index, const functional_vector& vector) const + [[nodiscard]] vector replacing_range_at(int index, const vector& vector) const { return replacing_range_at_imp(index, vector.begin(), vector.end()); } @@ -1310,7 +1310,7 @@ class functional_vector // // outcome: // replaced_numbers -> functional_vector({ 1, 4, 2, 5, 9, -10, 8, 7, 1 }) - [[nodiscard]] functional_vector replacing_range_at(int index, const std::vector& vector) const + [[nodiscard]] vector replacing_range_at(int index, const std::vector& vector) const { return replacing_range_at_imp(index, vector.cbegin(), vector.cend()); } @@ -1323,7 +1323,7 @@ class functional_vector // // outcome: // replaced_numbers -> functional_vector({ 1, 4, 2, 5, 9, -10, 8, 7, 1 }) - [[nodiscard]] functional_vector replacing_range_at(int index, const std::initializer_list& list) const + [[nodiscard]] vector replacing_range_at(int index, const std::initializer_list& list) const { return replacing_range_at(index, std::vector(list)); } @@ -1336,7 +1336,7 @@ class functional_vector // // outcome: // numbers -> functional_vector({ 7, 7, 7, 7, 7 }) - functional_vector& fill(const T& element) + vector& fill(const T& element) { std::fill(backing_vector_.begin(), backing_vector_.end(), @@ -1351,7 +1351,7 @@ class functional_vector } // Clears the vector by removing all elements (mutating) - functional_vector& clear() + vector& clear() { backing_vector_.clear(); return *this; @@ -1371,7 +1371,7 @@ class functional_vector // Reserves the necessary memory for `count` elements, so that subsequent changes in the // vector's size due to addition/removal of elements is more performant - functional_vector& reserve(size_t count) + vector& reserve(size_t count) { backing_vector_.reserve(count); return *this; @@ -1399,7 +1399,7 @@ class functional_vector // // empty_numbers.size() = 5 // // empty_numbers -> functional_vector({0, 0, 0, 0, 0}); // empty_numbers.resize(5); - functional_vector& resize(size_t count) + vector& resize(size_t count) { backing_vector_.resize(count); return *this; @@ -1438,8 +1438,8 @@ class functional_vector // outcome: // unique_numbers -> functional_set({1, 2, 3, 4, 5, 7, 8}) template > - functional_set distinct() const { - return functional_set(*this); + set distinct() const { + return set(*this); } // Returns a reference to the element in the given index, allowing subscripting and value editing. @@ -1459,7 +1459,7 @@ class functional_vector } // Returns true if both instances have equal sizes and the corresponding elements (same index) are equal - bool operator ==(const functional_vector& rhs) const + bool operator ==(const vector& rhs) const { #ifdef CPP17_AVAILABLE return std::equal(begin(), @@ -1482,7 +1482,7 @@ class functional_vector } // Returns false if either the sizes are not equal or at least one corresponding element (same index) is not equal - bool operator !=(const functional_vector& rhs) const + bool operator !=(const vector& rhs) const { return !((*this) == rhs); } @@ -1495,7 +1495,7 @@ class functional_vector #else template #endif - functional_vector& insert_back_range_impl(const Iterator& vec_begin, const Iterator& vec_end) + vector& insert_back_range_impl(const Iterator& vec_begin, const Iterator& vec_end) { backing_vector_.insert(backing_vector_.end(), vec_begin, @@ -1508,7 +1508,7 @@ class functional_vector #else template #endif - functional_vector& insert_front_range_impl(const Iterator& vec_begin, const Iterator& vec_end) + vector& insert_front_range_impl(const Iterator& vec_begin, const Iterator& vec_end) { backing_vector_.insert(backing_vector_.begin(), vec_begin, @@ -1521,14 +1521,14 @@ class functional_vector #else template #endif - [[nodiscard]] functional_vector inserting_back_range_impl(const Iterator& vec_begin, const Iterator& vec_end) const + [[nodiscard]] vector inserting_back_range_impl(const Iterator& vec_begin, const Iterator& vec_end) const { auto augmented_vector(backing_vector_); augmented_vector.reserve(augmented_vector.size() + std::distance(vec_begin, vec_end)); augmented_vector.insert(augmented_vector.end(), vec_begin, vec_end); - return functional_vector(augmented_vector); + return vector(augmented_vector); } #ifdef CPP17_AVAILABLE @@ -1536,14 +1536,14 @@ class functional_vector #else template #endif - [[nodiscard]] functional_vector inserting_front_range_impl(const Iterator& vec_begin, const Iterator& vec_end) const + [[nodiscard]] vector inserting_front_range_impl(const Iterator& vec_begin, const Iterator& vec_end) const { auto augmented_vector(backing_vector_); augmented_vector.reserve(augmented_vector.size() + std::distance(vec_begin, vec_end)); augmented_vector.insert(augmented_vector.begin(), vec_begin, vec_end); - return functional_vector(augmented_vector); + return vector(augmented_vector); } #ifdef CPP17_AVAILABLE @@ -1554,7 +1554,7 @@ class functional_vector using U = deref_type; #else template - [[nodiscard]] functional_vector> zip_impl(const typename std::vector::const_iterator& vec_begin, + [[nodiscard]] vector> zip_impl(const typename std::vector::const_iterator& vec_begin, const typename std::vector::const_iterator& vec_end) const { #endif @@ -1566,7 +1566,7 @@ class functional_vector { combined_vector.push_back({backing_vector_[i], *(vec_begin + i)}); } - return functional_vector>(std::move(combined_vector)); + return vector>(std::move(combined_vector)); } #ifdef CPP17_AVAILABLE @@ -1575,7 +1575,7 @@ class functional_vector #else template #endif - functional_vector& insert_at_impl(int index, + vector& insert_at_impl(int index, const Iterator& vec_begin, const Iterator& vec_end) { @@ -1594,7 +1594,7 @@ class functional_vector #else template #endif - [[nodiscard]] functional_vector inserting_at_impl(int index, + [[nodiscard]] vector inserting_at_impl(int index, const Iterator& vec_begin, const Iterator& vec_end) const { @@ -1607,7 +1607,7 @@ class functional_vector augmented_vector.insert(augmented_vector.begin() + index, vec_begin, vec_end); - return functional_vector(std::move(augmented_vector)); + return vector(std::move(augmented_vector)); } #ifdef CPP17_AVAILABLE @@ -1615,7 +1615,7 @@ class functional_vector #else template #endif - functional_vector& replace_range_at_imp(int index, + vector& replace_range_at_imp(int index, const Iterator& vec_begin, const Iterator& vec_end) { @@ -1632,7 +1632,7 @@ class functional_vector #else template #endif - [[nodiscard]] functional_vector replacing_range_at_imp(int index, + [[nodiscard]] vector replacing_range_at_imp(int index, const Iterator& vec_begin, const Iterator& vec_end) const { @@ -1642,7 +1642,7 @@ class functional_vector std::copy(vec_begin, vec_end, replaced_vector.begin() + index); - return functional_vector(replaced_vector); + return vector(replaced_vector); } void assert_smaller_size(int index) const diff --git a/tests/functional_set_test.cc b/tests/set_test.cc similarity index 50% rename from tests/functional_set_test.cc rename to tests/set_test.cc index cd9290e..5a72fcc 100644 --- a/tests/functional_set_test.cc +++ b/tests/set_test.cc @@ -22,96 +22,96 @@ #include #include "warnings.h" -#include "functional_set.h" -#include "functional_vector.h" +#include "set.h" +#include "vector.h" #include "test_types.h" using namespace fcpp; template -void debug(functional_set& set) +void debug(set& set) { set.for_each([](const T& element) { std::cout << element << std::endl; }); } -void test_contents(const functional_set& set) { +void test_contents(const set& set) { EXPECT_EQ(3, set.size()); EXPECT_EQ(1, set[0]); EXPECT_EQ(3, set[1]); EXPECT_EQ(5, set[2]); } -TEST(FunctionalSetTest, EmptyConstructor) +TEST(SetTest, EmptyConstructor) { - const functional_set set_under_test; + const set set_under_test; EXPECT_EQ(0, set_under_test.size()); } -TEST(FunctionalSetTest, StdSetConstructor) +TEST(SetTest, StdSetConstructor) { - const functional_set set_under_test(std::set({1, 5, 3, 3})); + const set set_under_test(std::set({1, 5, 3, 3})); test_contents(set_under_test); } -TEST(FunctionalSetTest, StdVectorConstructor) +TEST(SetTest, StdVectorConstructor) { - const functional_set set_under_test(std::vector({1, 5, 3, 3})); + const set set_under_test(std::vector({1, 5, 3, 3})); test_contents(set_under_test); } -TEST(FunctionalSetTest, FunctionalVectorConstructor) +TEST(SetTest, FunctionalVectorConstructor) { - const functional_set set_under_test(functional_vector({1, 5, 3, 3})); + const set set_under_test(vector({1, 5, 3, 3})); test_contents(set_under_test); } -TEST(FunctionalSetTest, StdInitializerListConstructor) +TEST(SetTest, StdInitializerListConstructor) { - const functional_set set_under_test(std::initializer_list({1, 5, 3, 3})); + const set set_under_test(std::initializer_list({1, 5, 3, 3})); test_contents(set_under_test); } -TEST(FunctionalSetTest, Subscripting) +TEST(SetTest, Subscripting) { - const functional_set set_under_test(std::set({1, 5, 3, 3})); + const set set_under_test(std::set({1, 5, 3, 3})); test_contents(set_under_test); } -TEST(FunctionalSetTest, ConstSubscripting) +TEST(SetTest, ConstSubscripting) { - const functional_set set_under_test(std::set({1, 5, 3, 3})); + const set set_under_test(std::set({1, 5, 3, 3})); test_contents(set_under_test); } -TEST(FunctionalSetTest, Difference) +TEST(SetTest, Difference) { - const functional_set set1(std::set({1, 2, 3, 5, 7, 8, 10})); - const functional_set set2(std::set({2, 5, 7, 10, 15, 17})); + const set set1(std::set({1, 2, 3, 5, 7, 8, 10})); + const set set2(std::set({2, 5, 7, 10, 15, 17})); const auto& diff = set1.difference_with(set2); - EXPECT_EQ(functional_set({1, 3, 8}), diff); + EXPECT_EQ(set({1, 3, 8}), diff); } -TEST(FunctionalSetTest, DifferenceStdSet) +TEST(SetTest, DifferenceStdSet) { - const functional_set set1(std::set({1, 2, 3, 5, 7, 8, 10})); + const set set1(std::set({1, 2, 3, 5, 7, 8, 10})); const std::set set2({2, 5, 7, 10, 15, 17}); const auto& diff = set1.difference_with(set2); - EXPECT_EQ(functional_set({1, 3, 8}), diff); + EXPECT_EQ(set({1, 3, 8}), diff); } -TEST(FunctionalSetTest, DifferenceFunctionalSet) +TEST(SetTest, DifferenceFunctionalSet) { - const functional_set set1({1, 2, 3, 5, 7, 8, 10}); - const functional_set set2({2, 5, 7, 10, 15, 17}); + const set set1({1, 2, 3, 5, 7, 8, 10}); + const set set2({2, 5, 7, 10, 15, 17}); const auto& diff = set1.difference_with(set2); - EXPECT_EQ(functional_set({1, 3, 8}), diff); + EXPECT_EQ(set({1, 3, 8}), diff); } -TEST(FunctionalSetTest, DifferenceFunctionalSetCustomType) +TEST(SetTest, DifferenceFunctionalSetCustomType) { - const functional_set set1({ + const set set1({ person(51, "George"), person(81, "Jackie"), person(15, "Jake"), @@ -119,14 +119,14 @@ TEST(FunctionalSetTest, DifferenceFunctionalSetCustomType) person(25, "Kate") }); - const functional_set set2({ + const set set2({ person(51, "George"), person(81, "Jackie"), }); const auto& diff = set1.difference_with(set2); - const functional_set expected({ + const set expected({ person(15, "Jake"), person(18, "Jannet"), person(25, "Kate") @@ -135,46 +135,46 @@ TEST(FunctionalSetTest, DifferenceFunctionalSetCustomType) EXPECT_EQ(expected, diff); } -TEST(FunctionalSetTest, Union) +TEST(SetTest, Union) { - const functional_set set1(std::set({1, 2, 3, 5, 7, 8, 10})); - const functional_set set2(std::set({2, 5, 7, 10, 15, 17})); + const set set1(std::set({1, 2, 3, 5, 7, 8, 10})); + const set set2(std::set({2, 5, 7, 10, 15, 17})); const auto& combined = set1.union_with(set2); - EXPECT_EQ(functional_set({1, 2, 3, 5, 7, 8, 10, 15, 17}), combined); + EXPECT_EQ(set({1, 2, 3, 5, 7, 8, 10, 15, 17}), combined); } -TEST(FunctionalSetTest, UnionStdSet) +TEST(SetTest, UnionStdSet) { - const functional_set set1(std::set({1, 2, 3, 5, 7, 8, 10})); + const set set1(std::set({1, 2, 3, 5, 7, 8, 10})); const std::set set2({2, 5, 7, 10, 15, 17}); const auto& combined = set1.union_with(set2); - EXPECT_EQ(functional_set({1, 2, 3, 5, 7, 8, 10, 15, 17}), combined); + EXPECT_EQ(set({1, 2, 3, 5, 7, 8, 10, 15, 17}), combined); } -TEST(FunctionalSetTest, UnionFunctionalSet) +TEST(SetTest, UnionFunctionalSet) { - const functional_set set1({1, 2, 3, 5, 7, 8, 10}); - const functional_set set2({2, 5, 7, 10, 15, 17}); + const set set1({1, 2, 3, 5, 7, 8, 10}); + const set set2({2, 5, 7, 10, 15, 17}); const auto& combined = set1.union_with(set2); - EXPECT_EQ(functional_set({1, 2, 3, 5, 7, 8, 10, 15, 17}), combined); + EXPECT_EQ(set({1, 2, 3, 5, 7, 8, 10, 15, 17}), combined); } -TEST(FunctionalSetTest, UnionFunctionalSetCustomType) +TEST(SetTest, UnionFunctionalSetCustomType) { - const functional_set set1({ + const set set1({ person(15, "Jake"), person(18, "Jannet"), person(25, "Kate") }); - const functional_set set2({ + const set set2({ person(51, "George"), person(81, "Jackie"), }); const auto& combined = set1.union_with(set2); - const functional_set expected({ + const set expected({ person(15, "Jake"), person(18, "Jannet"), person(25, "Kate"), @@ -185,33 +185,33 @@ TEST(FunctionalSetTest, UnionFunctionalSetCustomType) EXPECT_EQ(expected, combined); } -TEST(FunctionalSetTest, Intersection) +TEST(SetTest, Intersection) { - const functional_set set1(std::set({1, 2, 3, 5, 7, 8, 10})); - const functional_set set2(std::set({2, 5, 7, 10, 15, 17})); + const set set1(std::set({1, 2, 3, 5, 7, 8, 10})); + const set set2(std::set({2, 5, 7, 10, 15, 17})); const auto& intersection = set1.intersect_with(set2); - EXPECT_EQ(functional_set({2, 5, 7, 10}), intersection); + EXPECT_EQ(set({2, 5, 7, 10}), intersection); } -TEST(FunctionalSetTest, IntersectionStdSet) +TEST(SetTest, IntersectionStdSet) { - const functional_set set1(std::set({1, 2, 3, 5, 7, 8, 10})); + const set set1(std::set({1, 2, 3, 5, 7, 8, 10})); const std::set set2({2, 5, 7, 10, 15, 17}); const auto& intersection = set1.intersect_with(set2); - EXPECT_EQ(functional_set({2, 5, 7, 10}), intersection); + EXPECT_EQ(set({2, 5, 7, 10}), intersection); } -TEST(FunctionalSetTest, IntersectionFunctionalSet) +TEST(SetTest, IntersectionFunctionalSet) { - const functional_set set1({1, 2, 3, 5, 7, 8, 10}); - const functional_set set2({2, 5, 7, 10, 15, 17}); + const set set1({1, 2, 3, 5, 7, 8, 10}); + const set set2({2, 5, 7, 10, 15, 17}); const auto& intersection = set1.intersect_with(set2); - EXPECT_EQ(functional_set({2, 5, 7, 10}), intersection); + EXPECT_EQ(set({2, 5, 7, 10}), intersection); } -TEST(FunctionalSetTest, IntersectionFunctionalSetCustomType) +TEST(SetTest, IntersectionFunctionalSetCustomType) { - const functional_set set1({ + const set set1({ person(15, "Jake"), person(18, "Jannet"), person(25, "Kate"), @@ -219,7 +219,7 @@ TEST(FunctionalSetTest, IntersectionFunctionalSetCustomType) person(81, "Jackie"), }); - const functional_set set2({ + const set set2({ person(39, "Robert"), person(18, "Jannet"), person(25, "Kate"), @@ -229,7 +229,7 @@ TEST(FunctionalSetTest, IntersectionFunctionalSetCustomType) const auto& intersection = set1.intersect_with(set2); - const functional_set expected({ + const set expected({ person(18, "Jannet"), person(25, "Kate"), }); @@ -237,17 +237,17 @@ TEST(FunctionalSetTest, IntersectionFunctionalSetCustomType) EXPECT_EQ(expected, intersection); } -TEST(FunctionalSetTest, Min) +TEST(SetTest, Min) { - const functional_set numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); + const set numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); const auto minimum = numbers.min(); EXPECT_TRUE(minimum.has_value()); EXPECT_EQ(1, minimum.value()); } -TEST(FunctionalSetTest, MinCustomType) +TEST(SetTest, MinCustomType) { - const functional_set persons({ + const set persons({ person(15, "Jake"), person(18, "Jannet"), person(25, "Kate"), @@ -261,24 +261,24 @@ TEST(FunctionalSetTest, MinCustomType) #endif } -TEST(FunctionalSetTest, MinEmptySet) +TEST(SetTest, MinEmptySet) { - const functional_set numbers; + const set numbers; const auto minimum = numbers.min(); EXPECT_FALSE(minimum.has_value()); } -TEST(FunctionalSetTest, Max) +TEST(SetTest, Max) { - const functional_set numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); + const set numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); const auto maximum = numbers.max(); EXPECT_TRUE(maximum.has_value()); EXPECT_EQ(8, maximum.value()); } -TEST(FunctionalSetTest, MaxCustomType) +TEST(SetTest, MaxCustomType) { - const functional_set persons({ + const set persons({ person(15, "Jake"), person(18, "Jannet"), person(25, "Kate"), @@ -293,16 +293,16 @@ TEST(FunctionalSetTest, MaxCustomType) #endif } -TEST(FunctionalSetTest, MaxEmptySet) +TEST(SetTest, MaxEmptySet) { - const functional_set numbers; + const set numbers; const auto maximum = numbers.max(); EXPECT_FALSE(maximum.has_value()); } -TEST(FunctionalSetTest, Map) +TEST(SetTest, Map) { - const functional_set numbers({4, 1, 3}); + const set numbers({4, 1, 3}); const auto mapped_set = numbers.map([](const int& age) { return child(age); }); @@ -312,52 +312,52 @@ TEST(FunctionalSetTest, Map) EXPECT_EQ(4, mapped_set[2].age); } -TEST(FunctionalSetTest, AllOf) +TEST(SetTest, AllOf) { - const functional_set numbers({1, 4, 2, 5, 8, 3}); + const set numbers({1, 4, 2, 5, 8, 3}); EXPECT_TRUE(numbers.all_of([](const int &number) { return number < 10; })); EXPECT_FALSE(numbers.all_of([](const int &number) { return number > 2; })); } -TEST(FunctionalSetTest, AnyOf) +TEST(SetTest, AnyOf) { - const functional_set numbers({1, 4, 2, 5, 8, 3}); + const set numbers({1, 4, 2, 5, 8, 3}); EXPECT_TRUE(numbers.any_of([](const int &number) { return number < 5; })); EXPECT_FALSE(numbers.any_of([](const int &number) { return number > 10; })); } -TEST(FunctionalSetTest, NoneOf) +TEST(SetTest, NoneOf) { - const functional_set numbers({1, 4, 2, 5, 8, 3}); + const set numbers({1, 4, 2, 5, 8, 3}); EXPECT_TRUE(numbers.none_of([](const int &number) { return number > 10; })); EXPECT_FALSE(numbers.none_of([](const int &number) { return number < 6; })); } -TEST(FunctionalSetTest, Filter) +TEST(SetTest, Filter) { - functional_set numbers({ 1, 3, -5, 2, -1, 9, -4 }); + set numbers({ 1, 3, -5, 2, -1, 9, -4 }); numbers.filter([](const int& element) { return element >= 1.5; }); - EXPECT_EQ(functional_set({2, 3, 9}), numbers); + EXPECT_EQ(set({2, 3, 9}), numbers); } -TEST(FunctionalSetTest, Filtered) +TEST(SetTest, Filtered) { - const functional_set numbers({ 1, 3, -5, 2, -1, 9, -4 }); + const set numbers({ 1, 3, -5, 2, -1, 9, -4 }); auto filtered_numbers = numbers.filtered([](const int& element) { return element >= 1.5; }); - EXPECT_EQ(functional_set({2, 3, 9}), filtered_numbers); - EXPECT_EQ(functional_set({ 1, 3, -5, 2, -1, 9, -4 }), numbers); + EXPECT_EQ(set({2, 3, 9}), filtered_numbers); + EXPECT_EQ(set({ 1, 3, -5, 2, -1, 9, -4 }), numbers); } -TEST(FunctionalSetTest, ZipWithFunctionalSet) +TEST(SetTest, ZipWithFunctionalSet) { - const functional_set ages({ 25, 45, 30, 63 }); - const functional_set persons({ "Jake", "Bob", "Michael", "Philipp" }); + const set ages({ 25, 45, 30, 63 }); + const set persons({ "Jake", "Bob", "Michael", "Philipp" }); const auto zipped = ages.zip(persons); - const auto expected = functional_set>({ + const auto expected = set>({ std::pair(25, "Bob"), std::pair(30, "Jake"), std::pair(45, "Michael"), @@ -366,19 +366,19 @@ TEST(FunctionalSetTest, ZipWithFunctionalSet) EXPECT_EQ(expected, zipped); } -TEST(FunctionalSetTest, ZipWithFunctionalSetDifferentSizes) +TEST(SetTest, ZipWithFunctionalSetDifferentSizes) { - const functional_set ages({ 25, 45, 30, 63 }); - const functional_set persons({ "Jake" }); + const set ages({ 25, 45, 30, 63 }); + const set persons({ "Jake" }); EXPECT_DEATH(ages.zip(persons), ""); } -TEST(FunctionalSetTest, ZipWithStdSet) +TEST(SetTest, ZipWithStdSet) { - const functional_set ages({ 25, 45, 30, 63 }); + const set ages({ 25, 45, 30, 63 }); const std::set persons({ "Jake", "Bob", "Michael", "Philipp" }); const auto zipped = ages.zip(persons); - const auto expected = functional_set>({ + const auto expected = set>({ std::pair(25, "Bob"), std::pair(30, "Jake"), std::pair(45, "Michael"), @@ -387,19 +387,19 @@ TEST(FunctionalSetTest, ZipWithStdSet) EXPECT_EQ(expected, zipped); } -TEST(FunctionalSetTest, ZipWithStdSetDifferentSizes) +TEST(SetTest, ZipWithStdSetDifferentSizes) { - const functional_set ages({ 25, 45, 30, 63 }); + const set ages({ 25, 45, 30, 63 }); const std::set persons({ "Jake" }); EXPECT_DEATH(ages.zip(persons), ""); } -TEST(FunctionalSetTest, ZipWithFunctionalVector) +TEST(SetTest, ZipWithFunctionalVector) { - const functional_set ages({ 25, 45, 30, 63 }); - const functional_vector persons({ "Jake", "Bob", "Michael", "Philipp" }); + const set ages({ 25, 45, 30, 63 }); + const vector persons({ "Jake", "Bob", "Michael", "Philipp" }); const auto zipped = ages.zip(persons); - const auto expected = functional_set>({ + const auto expected = set>({ std::pair(25, "Bob"), std::pair(30, "Jake"), std::pair(45, "Michael"), @@ -408,19 +408,19 @@ TEST(FunctionalSetTest, ZipWithFunctionalVector) EXPECT_EQ(expected, zipped); } -TEST(FunctionalSetTest, ZipWithFunctionalVectorDifferentSizes) +TEST(SetTest, ZipWithFunctionalVectorDifferentSizes) { - const functional_set ages({ 25, 45, 30, 63 }); - const functional_vector persons({ "Jake" }); + const set ages({ 25, 45, 30, 63 }); + const vector persons({ "Jake" }); EXPECT_DEATH(ages.zip(persons), ""); } -TEST(FunctionalSetTest, ZipWithStdVector) +TEST(SetTest, ZipWithStdVector) { - const functional_set ages({ 25, 45, 30, 63 }); + const set ages({ 25, 45, 30, 63 }); const std::vector persons({ "Jake", "Bob", "Michael", "Philipp" }); const auto zipped = ages.zip(persons); - const auto expected = functional_set>({ + const auto expected = set>({ std::pair(25, "Bob"), std::pair(30, "Jake"), std::pair(45, "Michael"), @@ -429,112 +429,112 @@ TEST(FunctionalSetTest, ZipWithStdVector) EXPECT_EQ(expected, zipped); } -TEST(FunctionalSetTest, ZipWithStdVectorDifferentSizes) +TEST(SetTest, ZipWithStdVectorDifferentSizes) { - const functional_set ages({ 25, 45, 30, 63 }); + const set ages({ 25, 45, 30, 63 }); const std::vector persons({ "Jake" }); EXPECT_DEATH(ages.zip(persons), ""); } -TEST(FunctionalSetTest, RemoveExistingElement) +TEST(SetTest, RemoveExistingElement) { - functional_set numbers({1, 4, 2}); + set numbers({1, 4, 2}); numbers.remove(4); - EXPECT_EQ(functional_set({1, 2}), numbers); + EXPECT_EQ(set({1, 2}), numbers); } -TEST(FunctionalSetTest, RemoveNonExistentElement) +TEST(SetTest, RemoveNonExistentElement) { - functional_set numbers({1, 4, 2}); + set numbers({1, 4, 2}); numbers.remove(18); - EXPECT_EQ(functional_set({1, 2, 4}), numbers); + EXPECT_EQ(set({1, 2, 4}), numbers); } -TEST(FunctionalSetTest, RemovingExistingElement) +TEST(SetTest, RemovingExistingElement) { - const functional_set numbers({1, 4, 2}); + const set numbers({1, 4, 2}); const auto less_numbers = numbers.removing(4); - EXPECT_EQ(functional_set({1, 2}), less_numbers); - EXPECT_EQ(functional_set({1, 2, 4}), numbers); + EXPECT_EQ(set({1, 2}), less_numbers); + EXPECT_EQ(set({1, 2, 4}), numbers); } -TEST(FunctionalSetTest, InsertNewElement) +TEST(SetTest, InsertNewElement) { - functional_set numbers({1, 4, 2}); + set numbers({1, 4, 2}); numbers.insert(18); - EXPECT_EQ(functional_set({1, 2, 4, 18}), numbers); + EXPECT_EQ(set({1, 2, 4, 18}), numbers); } -TEST(FunctionalSetTest, InsertingNewElement) +TEST(SetTest, InsertingNewElement) { - const functional_set numbers({1, 4, 2}); + const set numbers({1, 4, 2}); const auto augmented_numbers = numbers.inserting(18); - EXPECT_EQ(functional_set({1, 2, 4, 18}), augmented_numbers); - EXPECT_EQ(functional_set({1, 2, 4}), numbers); + EXPECT_EQ(set({1, 2, 4, 18}), augmented_numbers); + EXPECT_EQ(set({1, 2, 4}), numbers); } -TEST(FunctionalSetTest, InsertExistingElement) +TEST(SetTest, InsertExistingElement) { - functional_set numbers({1, 4, 2}); + set numbers({1, 4, 2}); numbers.insert(2); - EXPECT_EQ(functional_set({1, 2, 4}), numbers); + EXPECT_EQ(set({1, 2, 4}), numbers); } -TEST(FunctionalSetTest, InsertingExistingElement) +TEST(SetTest, InsertingExistingElement) { - const functional_set numbers({1, 4, 2}); + const set numbers({1, 4, 2}); const auto augmented_numbers = numbers.inserting(2); - EXPECT_EQ(functional_set({1, 2, 4}), augmented_numbers); - EXPECT_EQ(functional_set({1, 2, 4}), numbers); + EXPECT_EQ(set({1, 2, 4}), augmented_numbers); + EXPECT_EQ(set({1, 2, 4}), numbers); } -TEST(FunctionalSetTest, Clear) +TEST(SetTest, Clear) { - functional_set numbers({1, 4, 2}); + set numbers({1, 4, 2}); numbers.clear(); EXPECT_EQ(0, numbers.size()); } -TEST(FunctionalSetTest, Clearing) +TEST(SetTest, Clearing) { - const functional_set numbers({1, 4, 2}); + const set numbers({1, 4, 2}); const auto cleared_numbers = numbers.clearing(); EXPECT_EQ(0, cleared_numbers.size()); EXPECT_EQ(3, numbers.size()); } -TEST(FunctionalSetTest, Contains) +TEST(SetTest, Contains) { - const functional_set numbers({1, 4, 2}); + const set numbers({1, 4, 2}); EXPECT_TRUE(numbers.contains(1)); EXPECT_FALSE(numbers.contains(15)); } -TEST(FunctionalSetTest, EqualityOperator) +TEST(SetTest, EqualityOperator) { - const functional_set set1(std::set({1, 2, 3})); - const functional_set set2(std::set({1, 2, 3, 2, 3})); + const set set1(std::set({1, 2, 3})); + const set set2(std::set({1, 2, 3, 2, 3})); EXPECT_TRUE(set1 == set2); EXPECT_FALSE(set1 != set2); } -TEST(FunctionalSetTest, InequalityOperator) +TEST(SetTest, InequalityOperator) { - const functional_set set1(std::set({1, 2, 3})); - const functional_set set2(std::set({1, 2, 3, 4})); + const set set1(std::set({1, 2, 3})); + const set set2(std::set({1, 2, 3, 4})); EXPECT_FALSE(set1 == set2); EXPECT_TRUE(set1 != set2); } -TEST(FunctionalSetTest, EqualityOperatorCustomType) +TEST(SetTest, EqualityOperatorCustomType) { - const functional_set set1({ + const set set1({ person(15, "Jake"), person(18, "Jannet"), person(25, "Kate") }); - const functional_set set2({ + const set set2({ person(15, "Jake"), person(18, "Jannet"), person(25, "Kate") diff --git a/tests/functional_vector_test.cc b/tests/vector_test.cc similarity index 54% rename from tests/functional_vector_test.cc rename to tests/vector_test.cc index b70b6b9..0842784 100644 --- a/tests/functional_vector_test.cc +++ b/tests/vector_test.cc @@ -22,8 +22,8 @@ #include #include -#include "functional_vector.h" -#include "functional_set.h" +#include "vector.h" +#include "set.h" #include "index_range.h" #include "test_types.h" #include "warnings.h" @@ -31,16 +31,16 @@ using namespace fcpp; template -void debug(const functional_vector& vec) +void debug(const vector& vec) { vec.for_each([](const T& element) { std::cout << element << std::endl; }); } -TEST(FunctionalVectorTest, InsertBack) +TEST(VectorTest, InsertBack) { - functional_vector vector_under_test; + vector vector_under_test; EXPECT_EQ(0, vector_under_test.size()); vector_under_test.insert_back(5); @@ -53,9 +53,9 @@ TEST(FunctionalVectorTest, InsertBack) EXPECT_EQ(-1, vector_under_test[1]); } -TEST(FunctionalVectorTest, InsertFront) +TEST(VectorTest, InsertFront) { - functional_vector vector_under_test; + vector vector_under_test; EXPECT_EQ(0, vector_under_test.size()); vector_under_test.insert_front(5); @@ -68,119 +68,119 @@ TEST(FunctionalVectorTest, InsertFront) EXPECT_EQ(5, vector_under_test[1]); } -TEST(FunctionalVectorTest, InsertingBack) +TEST(VectorTest, InsertingBack) { - const functional_vector vector_under_test({3, 6, 2, 8}); + const vector vector_under_test({3, 6, 2, 8}); const auto vector_new_instance = vector_under_test.inserting_back(5); EXPECT_EQ(4, vector_under_test.size()); EXPECT_EQ(3, vector_under_test[0]); EXPECT_EQ(8, vector_under_test[3]); - EXPECT_EQ(functional_vector({ 3, 6, 2, 8, 5 }), vector_new_instance); + EXPECT_EQ(vector({ 3, 6, 2, 8, 5 }), vector_new_instance); } -TEST(FunctionalVectorTest, InsertingFront) +TEST(VectorTest, InsertingFront) { - const functional_vector vector_under_test({3, 6, 2, 8}); + const vector vector_under_test({3, 6, 2, 8}); const auto vector_new_instance = vector_under_test.inserting_front(5); EXPECT_EQ(4, vector_under_test.size()); EXPECT_EQ(3, vector_under_test[0]); EXPECT_EQ(8, vector_under_test[3]); - EXPECT_EQ(functional_vector({ 5, 3, 6, 2, 8}), vector_new_instance); + EXPECT_EQ(vector({ 5, 3, 6, 2, 8}), vector_new_instance); } -TEST(FunctionalVectorTest, InsertBackFromFunctionalVector) +TEST(VectorTest, InsertBackFromFunctionalVector) { - functional_vector vector_under_test({ 4, 5, 6 }); - vector_under_test.insert_back(functional_vector({1, 2, 3})); - EXPECT_EQ(functional_vector({ 4, 5, 6, 1, 2, 3 }), vector_under_test); + vector vector_under_test({ 4, 5, 6 }); + vector_under_test.insert_back(vector({1, 2, 3})); + EXPECT_EQ(vector({ 4, 5, 6, 1, 2, 3 }), vector_under_test); } -TEST(FunctionalVectorTest, InsertBackFromStdVector) +TEST(VectorTest, InsertBackFromStdVector) { - functional_vector vector_under_test({ 4, 5, 6 }); + vector vector_under_test({ 4, 5, 6 }); vector_under_test.insert_back(std::vector{ 1, 2, 3 }); - EXPECT_EQ(functional_vector({ 4, 5, 6, 1, 2, 3 }), vector_under_test); + EXPECT_EQ(vector({ 4, 5, 6, 1, 2, 3 }), vector_under_test); } -TEST(FunctionalVectorTest, InsertBackFromInitializerList) +TEST(VectorTest, InsertBackFromInitializerList) { - functional_vector vector_under_test({ 4, 5, 6 }); + vector vector_under_test({ 4, 5, 6 }); vector_under_test.insert_back(std::initializer_list{ 1, 2, 3 }); - EXPECT_EQ(functional_vector({ 4, 5, 6, 1, 2, 3 }), vector_under_test); + EXPECT_EQ(vector({ 4, 5, 6, 1, 2, 3 }), vector_under_test); } -TEST(FunctionalVectorTest, InsertFrontFromFunctionalVector) +TEST(VectorTest, InsertFrontFromFunctionalVector) { - functional_vector vector_under_test({ 4, 5, 6 }); - vector_under_test.insert_front(functional_vector({1, 2, 3})); - EXPECT_EQ(functional_vector({ 1, 2, 3, 4, 5, 6 }), vector_under_test); + vector vector_under_test({ 4, 5, 6 }); + vector_under_test.insert_front(vector({1, 2, 3})); + EXPECT_EQ(vector({ 1, 2, 3, 4, 5, 6 }), vector_under_test); } -TEST(FunctionalVectorTest, InsertFrontFromStdVector) +TEST(VectorTest, InsertFrontFromStdVector) { - functional_vector vector_under_test({ 4, 5, 6 }); + vector vector_under_test({ 4, 5, 6 }); vector_under_test.insert_front(std::vector{ 1, 2, 3 }); - EXPECT_EQ(functional_vector({ 1, 2, 3, 4, 5, 6 }), vector_under_test); + EXPECT_EQ(vector({ 1, 2, 3, 4, 5, 6 }), vector_under_test); } -TEST(FunctionalVectorTest, InsertFrontFromInitializerList) +TEST(VectorTest, InsertFrontFromInitializerList) { - functional_vector vector_under_test({ 4, 5, 6 }); + vector vector_under_test({ 4, 5, 6 }); vector_under_test.insert_front(std::initializer_list{ 1, 2, 3 }); - EXPECT_EQ(functional_vector({ 1, 2, 3, 4, 5, 6 }), vector_under_test); + EXPECT_EQ(vector({ 1, 2, 3, 4, 5, 6 }), vector_under_test); } -TEST(FunctionalVectorTest, InsertingBackFromFunctionalVector) +TEST(VectorTest, InsertingBackFromFunctionalVector) { - const functional_vector vector_under_test({ 4, 5, 6 }); - const auto vector_new_instance = vector_under_test.inserting_back(functional_vector({1, 2, 3})); - EXPECT_EQ(functional_vector({ 4, 5, 6 }), vector_under_test); - EXPECT_EQ(functional_vector({ 4, 5, 6, 1, 2, 3 }), vector_new_instance); + const vector vector_under_test({ 4, 5, 6 }); + const auto vector_new_instance = vector_under_test.inserting_back(vector({1, 2, 3})); + EXPECT_EQ(vector({ 4, 5, 6 }), vector_under_test); + EXPECT_EQ(vector({ 4, 5, 6, 1, 2, 3 }), vector_new_instance); } -TEST(FunctionalVectorTest, InsertingBackFromStdVector) +TEST(VectorTest, InsertingBackFromStdVector) { - const functional_vector vector_under_test({ 4, 5, 6 }); + const vector vector_under_test({ 4, 5, 6 }); const auto vector_new_instance = vector_under_test.inserting_back(std::vector{ 1, 2, 3 }); - EXPECT_EQ(functional_vector({ 4, 5, 6 }), vector_under_test); - EXPECT_EQ(functional_vector({ 4, 5, 6, 1, 2, 3 }), vector_new_instance); + EXPECT_EQ(vector({ 4, 5, 6 }), vector_under_test); + EXPECT_EQ(vector({ 4, 5, 6, 1, 2, 3 }), vector_new_instance); } -TEST(FunctionalVectorTest, InsertingBackFromInitializerList) +TEST(VectorTest, InsertingBackFromInitializerList) { - const functional_vector vector_under_test({ 4, 5, 6 }); + const vector vector_under_test({ 4, 5, 6 }); const auto vector_new_instance = vector_under_test.inserting_back(std::initializer_list{ 1, 2, 3 }); - EXPECT_EQ(functional_vector({ 4, 5, 6 }), vector_under_test); - EXPECT_EQ(functional_vector({ 4, 5, 6, 1, 2, 3 }), vector_new_instance); + EXPECT_EQ(vector({ 4, 5, 6 }), vector_under_test); + EXPECT_EQ(vector({ 4, 5, 6, 1, 2, 3 }), vector_new_instance); } -TEST(FunctionalVectorTest, InsertingFrontFromFunctionalVector) +TEST(VectorTest, InsertingFrontFromFunctionalVector) { - const functional_vector vector_under_test({ 4, 5, 6 }); - const auto vector_new_instance = vector_under_test.inserting_front(functional_vector({1, 2, 3})); - EXPECT_EQ(functional_vector({ 4, 5, 6 }), vector_under_test); - EXPECT_EQ(functional_vector({ 1, 2, 3, 4, 5, 6 }), vector_new_instance); + const vector vector_under_test({ 4, 5, 6 }); + const auto vector_new_instance = vector_under_test.inserting_front(vector({1, 2, 3})); + EXPECT_EQ(vector({ 4, 5, 6 }), vector_under_test); + EXPECT_EQ(vector({ 1, 2, 3, 4, 5, 6 }), vector_new_instance); } -TEST(FunctionalVectorTest, InsertingFrontFromStdVector) +TEST(VectorTest, InsertingFrontFromStdVector) { - const functional_vector vector_under_test({ 4, 5, 6 }); + const vector vector_under_test({ 4, 5, 6 }); const auto vector_new_instance = vector_under_test.inserting_front(std::vector{ 1, 2, 3 }); - EXPECT_EQ(functional_vector({ 4, 5, 6 }), vector_under_test); - EXPECT_EQ(functional_vector({ 1, 2, 3, 4, 5, 6 }), vector_new_instance); + EXPECT_EQ(vector({ 4, 5, 6 }), vector_under_test); + EXPECT_EQ(vector({ 1, 2, 3, 4, 5, 6 }), vector_new_instance); } -TEST(FunctionalVectorTest, InsertingFrontFromInitializerList) +TEST(VectorTest, InsertingFrontFromInitializerList) { - const functional_vector vector_under_test({ 4, 5, 6 }); + const vector vector_under_test({ 4, 5, 6 }); const auto vector_new_instance = vector_under_test.inserting_front(std::initializer_list{ 1, 2, 3 }); - EXPECT_EQ(functional_vector({ 4, 5, 6 }), vector_under_test); - EXPECT_EQ(functional_vector({ 1, 2, 3, 4, 5, 6 }), vector_new_instance); + EXPECT_EQ(vector({ 4, 5, 6 }), vector_under_test); + EXPECT_EQ(vector({ 1, 2, 3, 4, 5, 6 }), vector_new_instance); } -TEST(FunctionalVectorTest, Map) +TEST(VectorTest, Map) { - const functional_vector vector_under_test({1, 3, 4}); + const vector vector_under_test({1, 3, 4}); const auto mapped_vector = vector_under_test.map([](const int& age) { return child(age); }); @@ -191,7 +191,7 @@ TEST(FunctionalVectorTest, Map) } #ifdef PARALLEL_ALGORITHM_AVAILABLE -TEST(FunctionalVectorTest, MapParallel) +TEST(VectorTest, MapParallel) { const functional_vector vector_under_test({1, 3, 4}); const auto mapped_vector = vector_under_test.map_parallel([](const int& age) { @@ -204,9 +204,9 @@ TEST(FunctionalVectorTest, MapParallel) } #endif -TEST(FunctionalVectorTest, Filter) +TEST(VectorTest, Filter) { - functional_vector vector_under_test({child(1), child(3), child(4)}); + vector vector_under_test({child(1), child(3), child(4)}); vector_under_test.filter([](const child& child) { return child.age < 2; }); @@ -219,7 +219,7 @@ TEST(FunctionalVectorTest, Filter) } #ifdef PARALLEL_ALGORITHM_AVAILABLE -TEST(FunctionalVectorTest, FilterParallel) +TEST(VectorTest, FilterParallel) { functional_vector vector_under_test({child(1), child(3), child(4)}); vector_under_test.filter_parallel([](const child& child) { @@ -234,9 +234,9 @@ TEST(FunctionalVectorTest, FilterParallel) } #endif -TEST(FunctionalVectorTest, Filtered) +TEST(VectorTest, Filtered) { - const functional_vector vector_under_test({child(1), child(3), child(4)}); + const vector vector_under_test({child(1), child(3), child(4)}); const auto filtered_vector = vector_under_test.filtered([](const child& child) { return child.age < 2; }); @@ -246,7 +246,7 @@ TEST(FunctionalVectorTest, Filtered) } #ifdef PARALLEL_ALGORITHM_AVAILABLE -TEST(FunctionalVectorTest, FilteredParallel) +TEST(VectorTest, FilteredParallel) { const functional_vector vector_under_test({child(1), child(3), child(4)}); const auto filtered_vector = vector_under_test.filtered_parallel([](const child& child) { @@ -258,9 +258,9 @@ TEST(FunctionalVectorTest, FilteredParallel) } #endif -TEST(FunctionalVectorTest, Reverse) +TEST(VectorTest, Reverse) { - functional_vector vector_under_test({child(6), child(2), child(9)}); + vector vector_under_test({child(6), child(2), child(9)}); vector_under_test.reverse(); EXPECT_EQ(3, vector_under_test.size()); EXPECT_EQ(9, vector_under_test[0].age); @@ -268,9 +268,9 @@ TEST(FunctionalVectorTest, Reverse) EXPECT_EQ(6, vector_under_test[2].age); } -TEST(FunctionalVectorTest, Reversed) +TEST(VectorTest, Reversed) { - const functional_vector vector_under_test({child(6), child(2), child(9)}); + const vector vector_under_test({child(6), child(2), child(9)}); const auto reversed_vector = vector_under_test.reversed(); EXPECT_EQ(3, reversed_vector.size()); EXPECT_EQ(9, reversed_vector[0].age); @@ -283,23 +283,23 @@ TEST(FunctionalVectorTest, Reversed) EXPECT_EQ(9, vector_under_test[2].age); } -TEST(FunctionalVectorTest, ZipWithStdVectorUnequalSizesThrows) +TEST(VectorTest, ZipWithStdVectorUnequalSizesThrows) { - const functional_vector ages_vector({32, 25, 53, 62}); + const vector ages_vector({32, 25, 53, 62}); EXPECT_DEATH({ const auto zipped_vector = ages_vector.zip(std::vector({"Jake", "Mary"})); }, ""); } -TEST(FunctionalVectorTest, ZipWithFunctionalVectorUnequalSizesThrows) +TEST(VectorTest, ZipWithFunctionalVectorUnequalSizesThrows) { - const functional_vector ages_vector({32, 25, 53, 62}); - const auto names_vector = functional_vector({"Jake", "Mary"}); + const vector ages_vector({32, 25, 53, 62}); + const auto names_vector = vector({"Jake", "Mary"}); EXPECT_DEATH({ const auto zipped_vector = ages_vector.zip(names_vector); }, ""); } -TEST(FunctionalVectorTest, ZipWithFunctionalVector) +TEST(VectorTest, ZipWithFunctionalVector) { - const functional_vector ages_vector({32, 25, 53}); - const functional_vector names_vector({"Jake", "Mary", "John"}); + const vector ages_vector({32, 25, 53}); + const vector names_vector({"Jake", "Mary", "John"}); const auto zipped_vector = ages_vector.zip(names_vector); EXPECT_EQ(3, zipped_vector.size()); @@ -313,9 +313,9 @@ TEST(FunctionalVectorTest, ZipWithFunctionalVector) EXPECT_EQ("John", zipped_vector[2].second); } -TEST(FunctionalVectorTest, ZipWithStdVector) +TEST(VectorTest, ZipWithStdVector) { - const functional_vector ages_vector({32, 25, 53}); + const vector ages_vector({32, 25, 53}); const auto zipped_vector = ages_vector.zip(std::vector{"Jake", "Mary", "John"}); EXPECT_EQ(3, zipped_vector.size()); @@ -329,9 +329,9 @@ TEST(FunctionalVectorTest, ZipWithStdVector) EXPECT_EQ("John", zipped_vector[2].second); } -TEST(FunctionalVectorTest, ZipWithInitializerList) +TEST(VectorTest, ZipWithInitializerList) { - const functional_vector ages_vector({32, 25, 53}); + const vector ages_vector({32, 25, 53}); const auto zipped_vector = ages_vector.zip(std::initializer_list{"Jake", "Mary", "John"}); EXPECT_EQ(3, zipped_vector.size()); @@ -345,9 +345,9 @@ TEST(FunctionalVectorTest, ZipWithInitializerList) EXPECT_EQ("John", zipped_vector[2].second); } -TEST(FunctionalVectorTest, Sort) +TEST(VectorTest, Sort) { - functional_vector vector_under_test({ + vector vector_under_test({ person(45, "Jake"), person(34, "Bob"), person(52, "Manfred"), person(8, "Alice") }); vector_under_test.sort([](const person& person1, const person& person2) @@ -369,9 +369,9 @@ TEST(FunctionalVectorTest, Sort) EXPECT_EQ(52, vector_under_test[3].age); } -TEST(FunctionalVectorTest, Sorted) +TEST(VectorTest, Sorted) { - const functional_vector vector_under_test({ + const vector vector_under_test({ person(45, "Jake"), person(34, "Bob"), person(52, "Manfred"), person(8, "Alice") }); const auto sorted_vector = vector_under_test.sorted([](const person& person1, const person& person2) { @@ -399,9 +399,9 @@ TEST(FunctionalVectorTest, Sorted) EXPECT_EQ(52, sorted_vector[3].age); } -TEST(FunctionalVectorTest, SortAscending) +TEST(VectorTest, SortAscending) { - functional_vector vector_under_test({3, 1, 9, -4}); + vector vector_under_test({3, 1, 9, -4}); vector_under_test.sort_ascending(); EXPECT_EQ(4, vector_under_test.size()); EXPECT_EQ(-4, vector_under_test[0]); @@ -410,9 +410,9 @@ TEST(FunctionalVectorTest, SortAscending) EXPECT_EQ(9, vector_under_test[3]); } -TEST(FunctionalVectorTest, SortedAscending) +TEST(VectorTest, SortedAscending) { - const functional_vector vector_under_test({3, 1, 9, -4}); + const vector vector_under_test({3, 1, 9, -4}); const auto sorted_vector = vector_under_test.sorted_ascending(); EXPECT_EQ(4, vector_under_test.size()); EXPECT_EQ(3, vector_under_test[0]); @@ -427,9 +427,9 @@ TEST(FunctionalVectorTest, SortedAscending) EXPECT_EQ(9, sorted_vector[3]); } -TEST(FunctionalVectorTest, SortDescending) +TEST(VectorTest, SortDescending) { - functional_vector vector_under_test({3, 1, 9, -4}); + vector vector_under_test({3, 1, 9, -4}); vector_under_test.sort_descending(); EXPECT_EQ(4, vector_under_test.size()); EXPECT_EQ(9, vector_under_test[0]); @@ -438,9 +438,9 @@ TEST(FunctionalVectorTest, SortDescending) EXPECT_EQ(-4, vector_under_test[3]); } -TEST(FunctionalVectorTest, SortedDescending) +TEST(VectorTest, SortedDescending) { - const functional_vector vector_under_test({3, 1, 9, -4}); + const vector vector_under_test({3, 1, 9, -4}); const auto sorted_vector = vector_under_test.sorted_descending(); EXPECT_EQ(4, vector_under_test.size()); EXPECT_EQ(3, vector_under_test[0]); @@ -456,7 +456,7 @@ TEST(FunctionalVectorTest, SortedDescending) } #ifdef PARALLEL_ALGORITHM_AVAILABLE -TEST(FunctionalVectorTest, SortParallel) +TEST(VectorTest, SortParallel) { functional_vector vector_under_test({ person(45, "Jake"), person(34, "Bob"), person(52, "Manfred"), person(8, "Alice") @@ -479,7 +479,7 @@ TEST(FunctionalVectorTest, SortParallel) EXPECT_EQ(52, vector_under_test[3].age); } -TEST(FunctionalVectorTest, SortedParallel) +TEST(VectorTest, SortedParallel) { const functional_vector vector_under_test({ person(45, "Jake"), person(34, "Bob"), person(52, "Manfred"), person(8, "Alice") @@ -509,7 +509,7 @@ TEST(FunctionalVectorTest, SortedParallel) EXPECT_EQ(52, sorted_vector[3].age); } -TEST(FunctionalVectorTest, SortAscendingParallel) +TEST(VectorTest, SortAscendingParallel) { functional_vector vector_under_test({3, 1, 9, -4}); vector_under_test.sort_ascending_parallel(); @@ -520,7 +520,7 @@ TEST(FunctionalVectorTest, SortAscendingParallel) EXPECT_EQ(9, vector_under_test[3]); } -TEST(FunctionalVectorTest, SortedAscendingParallel) +TEST(VectorTest, SortedAscendingParallel) { const functional_vector vector_under_test({3, 1, 9, -4}); const auto sorted_vector = vector_under_test.sorted_ascending_parallel(); @@ -537,7 +537,7 @@ TEST(FunctionalVectorTest, SortedAscendingParallel) EXPECT_EQ(9, sorted_vector[3]); } -TEST(FunctionalVectorTest, SortDescendingParallel) +TEST(VectorTest, SortDescendingParallel) { functional_vector vector_under_test({3, 1, 9, -4}); vector_under_test.sort_descending_parallel(); @@ -548,7 +548,7 @@ TEST(FunctionalVectorTest, SortDescendingParallel) EXPECT_EQ(-4, vector_under_test[3]); } -TEST(FunctionalVectorTest, SortedDescendingParallel) +TEST(VectorTest, SortedDescendingParallel) { const functional_vector vector_under_test({3, 1, 9, -4}); const auto sorted_vector = vector_under_test.sorted_descending_parallel(); @@ -566,45 +566,45 @@ TEST(FunctionalVectorTest, SortedDescendingParallel) } #endif -TEST(FunctionalVectorTest, SubscriptOperatorNegativeDeath) +TEST(VectorTest, SubscriptOperatorNegativeDeath) { - const functional_vector vector_under_test({3, 1, 9, -4}); + const vector vector_under_test({3, 1, 9, -4}); EXPECT_DEATH(vector_under_test[-1], ""); } -TEST(FunctionalVectorTest, SubscriptOperatorIndexEqualToSizeDeath) +TEST(VectorTest, SubscriptOperatorIndexEqualToSizeDeath) { - const functional_vector vector_under_test({3, 1, 9, -4}); + const vector vector_under_test({3, 1, 9, -4}); EXPECT_DEATH(vector_under_test[4], ""); } -TEST(FunctionalVectorTest, SubscriptOperatorIndexLargerThanSizeDeath) +TEST(VectorTest, SubscriptOperatorIndexLargerThanSizeDeath) { - const functional_vector vector_under_test({3, 1, 9, -4}); + const vector vector_under_test({3, 1, 9, -4}); EXPECT_DEATH(vector_under_test[5], ""); } -TEST(FunctionalVectorTest, SubscriptOperatorAssignNegativeDeath) +TEST(VectorTest, SubscriptOperatorAssignNegativeDeath) { - functional_vector vector_under_test({3, 1, 9, -4}); + vector vector_under_test({3, 1, 9, -4}); EXPECT_DEATH(vector_under_test[-1] = 5, ""); } -TEST(FunctionalVectorTest, SubscriptOperatorAssignIndexEqualSizeDeath) +TEST(VectorTest, SubscriptOperatorAssignIndexEqualSizeDeath) { - functional_vector vector_under_test({3, 1, 9, -4}); + vector vector_under_test({3, 1, 9, -4}); EXPECT_DEATH(vector_under_test[4] = 5, ""); } -TEST(FunctionalVectorTest, SubscriptOperatorAssignIndexLargerThanSizeDeath) +TEST(VectorTest, SubscriptOperatorAssignIndexLargerThanSizeDeath) { - functional_vector vector_under_test({3, 1, 9, -4}); + vector vector_under_test({3, 1, 9, -4}); EXPECT_DEATH(vector_under_test[5] = -3, ""); } -TEST(FunctionalVectorTest, SubscriptOperatorAssign) +TEST(VectorTest, SubscriptOperatorAssign) { - functional_vector vector_under_test({3, 1, 9, -4}); + vector vector_under_test({3, 1, 9, -4}); vector_under_test[2] = 7; EXPECT_EQ(4, vector_under_test.size()); EXPECT_EQ(3, vector_under_test[0]); @@ -613,173 +613,173 @@ TEST(FunctionalVectorTest, SubscriptOperatorAssign) EXPECT_EQ(-4, vector_under_test[3]); } -TEST(FunctionalVectorTest, FindFirstIndexEmptyVector) +TEST(VectorTest, FindFirstIndexEmptyVector) { - const functional_vector vector_under_test; + const vector vector_under_test; EXPECT_FALSE(vector_under_test.find_first_index(-3).has_value()); } -TEST(FunctionalVectorTest, FindFirstIndexFilledVectorWithoutMatch) +TEST(VectorTest, FindFirstIndexFilledVectorWithoutMatch) { - const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + const vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_FALSE(vector_under_test.find_first_index(9).has_value()); } -TEST(FunctionalVectorTest, FindFirstIndexFilledVector) +TEST(VectorTest, FindFirstIndexFilledVector) { - const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + const vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_EQ(0, vector_under_test.find_first_index(1).value()); EXPECT_EQ(7, vector_under_test.find_first_index(7).value()); EXPECT_EQ(3, vector_under_test.find_first_index(5).value()); } -TEST(FunctionalVectorTest, FindLastIndexEmptyVector) +TEST(VectorTest, FindLastIndexEmptyVector) { - const functional_vector vector_under_test; + const vector vector_under_test; EXPECT_FALSE(vector_under_test.find_last_index(-3).has_value()); } -TEST(FunctionalVectorTest, FindLastIndexFilledVectorWithoutMatch) +TEST(VectorTest, FindLastIndexFilledVectorWithoutMatch) { - const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + const vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_FALSE(vector_under_test.find_last_index(9).has_value()); } -TEST(FunctionalVectorTest, FindLastIndexFilledVector) +TEST(VectorTest, FindLastIndexFilledVector) { - const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + const vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_EQ(8, vector_under_test.find_last_index(1).value()); EXPECT_EQ(7, vector_under_test.find_last_index(7).value()); EXPECT_EQ(3, vector_under_test.find_last_index(5).value()); } -TEST(FunctionalVectorTest, FindAllIndicesEmptyVector) +TEST(VectorTest, FindAllIndicesEmptyVector) { - const functional_vector vector_under_test; + const vector vector_under_test; EXPECT_EQ(0, vector_under_test.find_all_indices(-3).size()); } -TEST(FunctionalVectorTest, FindAllIndicesFilledVectorWithoutMatch) +TEST(VectorTest, FindAllIndicesFilledVectorWithoutMatch) { - const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + const vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_EQ(0, vector_under_test.find_all_indices(9).size()); } -TEST(FunctionalVectorTest, FindAllIndicesFilledVector) +TEST(VectorTest, FindAllIndicesFilledVector) { - const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 9, 1}); + const vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 9, 1}); const auto one_indices = vector_under_test.find_all_indices(1); EXPECT_EQ(std::vector({ 0, 6, 8 }), one_indices); const auto seven_indices = vector_under_test.find_all_indices(9); EXPECT_EQ(std::vector({ 7 }), seven_indices); } -TEST(FunctionalVectorTest, RemoveAtEmptyVector) +TEST(VectorTest, RemoveAtEmptyVector) { - functional_vector vector_under_test; + vector vector_under_test; EXPECT_DEATH(vector_under_test.remove_at(-1), ""); EXPECT_DEATH(vector_under_test.remove_at(0), ""); EXPECT_DEATH(vector_under_test.remove_at(1), ""); } -TEST(FunctionalVectorTest, RemoveAtFilledVectorAboveSize) +TEST(VectorTest, RemoveAtFilledVectorAboveSize) { - auto vector_under_test = functional_vector({1, 4, 2, 5, 8, 3, 1, 7, 1}); + auto vector_under_test = vector({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_DEATH(vector_under_test.remove_at(15), ""); } -TEST(FunctionalVectorTest, RemoveAtFilledVector) +TEST(VectorTest, RemoveAtFilledVector) { - functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); vector_under_test.remove_at(1); - EXPECT_EQ(functional_vector({ 1, 2, 5, 8, 3, 1, 7, 1 }), vector_under_test); + EXPECT_EQ(vector({ 1, 2, 5, 8, 3, 1, 7, 1 }), vector_under_test); vector_under_test.remove_at(1); - EXPECT_EQ(functional_vector({ 1, 5, 8, 3, 1, 7, 1 }), vector_under_test); + EXPECT_EQ(vector({ 1, 5, 8, 3, 1, 7, 1 }), vector_under_test); vector_under_test.remove_at(4); - EXPECT_EQ(functional_vector({ 1, 5, 8, 3, 7, 1 }), vector_under_test); + EXPECT_EQ(vector({ 1, 5, 8, 3, 7, 1 }), vector_under_test); } -TEST(FunctionalVectorTest, RemovingAtEmptyVector) +TEST(VectorTest, RemovingAtEmptyVector) { - const functional_vector vector_under_test; + const vector vector_under_test; EXPECT_DEATH(vector_under_test.removing_at(-1), ""); EXPECT_DEATH(vector_under_test.removing_at(0), ""); EXPECT_DEATH(vector_under_test.removing_at(1), ""); } -TEST(FunctionalVectorTest, RemovingAtFilledVectorAboveSize) +TEST(VectorTest, RemovingAtFilledVectorAboveSize) { - const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + const vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_DEATH(vector_under_test.removing_at(15), ""); } -TEST(FunctionalVectorTest, RemovingAtFilledVector) +TEST(VectorTest, RemovingAtFilledVector) { - const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + const vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); const auto shorter_vector = vector_under_test.removing_at(1); - EXPECT_EQ(functional_vector({ 1, 2, 5, 8, 3, 1, 7, 1 }), shorter_vector); - EXPECT_EQ(functional_vector({ 1, 4, 2, 5, 8, 3, 1, 7, 1 }), vector_under_test); + EXPECT_EQ(vector({ 1, 2, 5, 8, 3, 1, 7, 1 }), shorter_vector); + EXPECT_EQ(vector({ 1, 4, 2, 5, 8, 3, 1, 7, 1 }), vector_under_test); } -TEST(FunctionalVectorTest, RemoveBack) +TEST(VectorTest, RemoveBack) { - functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); vector_under_test.remove_back(); - EXPECT_EQ(functional_vector({ 1, 4, 2, 5, 8, 3, 1, 7 }), vector_under_test); + EXPECT_EQ(vector({ 1, 4, 2, 5, 8, 3, 1, 7 }), vector_under_test); vector_under_test.remove_back(); - EXPECT_EQ(functional_vector({ 1, 4, 2, 5, 8, 3, 1 }), vector_under_test); + EXPECT_EQ(vector({ 1, 4, 2, 5, 8, 3, 1 }), vector_under_test); vector_under_test.remove_back(); - EXPECT_EQ(functional_vector({ 1, 4, 2, 5, 8, 3 }), vector_under_test); + EXPECT_EQ(vector({ 1, 4, 2, 5, 8, 3 }), vector_under_test); } -TEST(FunctionalVectorTest, RemovingBack) +TEST(VectorTest, RemovingBack) { - const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + const vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); const auto vector_without_last_element = vector_under_test.removing_back(); - EXPECT_EQ(functional_vector({ 1, 4, 2, 5, 8, 3, 1, 7 }), vector_without_last_element); - EXPECT_EQ(functional_vector({ 1, 4, 2, 5, 8, 3, 1, 7, 1 }), vector_under_test); + EXPECT_EQ(vector({ 1, 4, 2, 5, 8, 3, 1, 7 }), vector_without_last_element); + EXPECT_EQ(vector({ 1, 4, 2, 5, 8, 3, 1, 7, 1 }), vector_under_test); } -TEST(FunctionalVectorTest, RemoveFront) +TEST(VectorTest, RemoveFront) { - functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); vector_under_test.remove_front(); - EXPECT_EQ(functional_vector({ 4, 2, 5, 8, 3, 1, 7, 1 }), vector_under_test); + EXPECT_EQ(vector({ 4, 2, 5, 8, 3, 1, 7, 1 }), vector_under_test); vector_under_test.remove_front(); - EXPECT_EQ(functional_vector({ 2, 5, 8, 3, 1, 7, 1 }), vector_under_test); + EXPECT_EQ(vector({ 2, 5, 8, 3, 1, 7, 1 }), vector_under_test); vector_under_test.remove_front(); - EXPECT_EQ(functional_vector({ 5, 8, 3, 1, 7, 1 }), vector_under_test); + EXPECT_EQ(vector({ 5, 8, 3, 1, 7, 1 }), vector_under_test); } -TEST(FunctionalVectorTest, RemovingFront) +TEST(VectorTest, RemovingFront) { - const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + const vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); const auto vector_without_first_element = vector_under_test.removing_front(); - EXPECT_EQ(functional_vector({ 4, 2, 5, 8, 3, 1, 7, 1 }), vector_without_first_element); - EXPECT_EQ(functional_vector({ 1, 4, 2, 5, 8, 3, 1, 7, 1 }), vector_under_test); + EXPECT_EQ(vector({ 4, 2, 5, 8, 3, 1, 7, 1 }), vector_without_first_element); + EXPECT_EQ(vector({ 1, 4, 2, 5, 8, 3, 1, 7, 1 }), vector_under_test); } -TEST(FunctionalVectorTest, InsertAtEmptyVector) +TEST(VectorTest, InsertAtEmptyVector) { - functional_vector vector_under_test; + vector vector_under_test; EXPECT_DEATH(vector_under_test.insert_at(15, -1), ""); vector_under_test.insert_at(0, -1); EXPECT_EQ(1, vector_under_test.size()); EXPECT_EQ(-1, vector_under_test[0]); } -TEST(FunctionalVectorTest, InsertAtFilledVector) +TEST(VectorTest, InsertAtFilledVector) { - functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_DEATH(vector_under_test.insert_at(15, -1), ""); vector_under_test.insert_at(3, 18); - EXPECT_EQ(functional_vector({ 1, 4, 2, 18, 5, 8, 3, 1, 7, 1 }), vector_under_test); + EXPECT_EQ(vector({ 1, 4, 2, 18, 5, 8, 3, 1, 7, 1 }), vector_under_test); } -TEST(FunctionalVectorTest, InsertingAtEmptyVector) +TEST(VectorTest, InsertingAtEmptyVector) { - const functional_vector vector_under_test; + const vector vector_under_test; EXPECT_DEATH(vector_under_test.inserting_at(15, -1), ""); const auto augmented_vector = vector_under_test.inserting_at(0, -1); EXPECT_EQ(1, augmented_vector.size()); @@ -787,347 +787,347 @@ TEST(FunctionalVectorTest, InsertingAtEmptyVector) EXPECT_EQ(0, vector_under_test.size()); } -TEST(FunctionalVectorTest, InsertingAtFilledVector) +TEST(VectorTest, InsertingAtFilledVector) { - const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + const vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_DEATH(vector_under_test.inserting_at(15, -1), ""); const auto augmented_vector = vector_under_test.inserting_at(3, 18); - EXPECT_EQ(functional_vector({ 1, 4, 2, 18, 5, 8, 3, 1, 7, 1 }), augmented_vector); - EXPECT_EQ(functional_vector({ 1, 4, 2, 5, 8, 3, 1, 7, 1 }), vector_under_test); + EXPECT_EQ(vector({ 1, 4, 2, 18, 5, 8, 3, 1, 7, 1 }), augmented_vector); + EXPECT_EQ(vector({ 1, 4, 2, 5, 8, 3, 1, 7, 1 }), vector_under_test); } -TEST(FunctionalVectorTest, InsertRangeEmptyFunctionalVector) +TEST(VectorTest, InsertRangeEmptyFunctionalVector) { - functional_vector vector_under_test; - const functional_vector vector_to_insert({4, 7, 3, -5}); + vector vector_under_test; + const vector vector_to_insert({4, 7, 3, -5}); vector_under_test.insert_at(0, vector_to_insert); - EXPECT_EQ(functional_vector({ 4, 7, 3, -5 }), vector_under_test); + EXPECT_EQ(vector({ 4, 7, 3, -5 }), vector_under_test); } -TEST(FunctionalVectorTest, InsertRangeExistingWrongInsertionIndexFunctionalVector) +TEST(VectorTest, InsertRangeExistingWrongInsertionIndexFunctionalVector) { - functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); - const functional_vector vector_to_insert({9, -5, 6}); + vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + const vector vector_to_insert({9, -5, 6}); EXPECT_DEATH(vector_under_test.insert_at(-1, vector_to_insert), ""); EXPECT_DEATH(vector_under_test.insert_at(10, vector_to_insert), ""); } -TEST(FunctionalVectorTest, InsertRangeExistingFunctionalVector) +TEST(VectorTest, InsertRangeExistingFunctionalVector) { - functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); - const functional_vector vector_to_insert({9, -5, 6}); + vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + const vector vector_to_insert({9, -5, 6}); vector_under_test.insert_at(3, vector_to_insert); - EXPECT_EQ(functional_vector({ 1, 4, 2, 9, -5, 6, 5, 8, 3, 1, 7, 1 }), vector_under_test); + EXPECT_EQ(vector({ 1, 4, 2, 9, -5, 6, 5, 8, 3, 1, 7, 1 }), vector_under_test); } -TEST(FunctionalVectorTest, InsertRangeEmptyStdVector) +TEST(VectorTest, InsertRangeEmptyStdVector) { - functional_vector vector_under_test; + vector vector_under_test; const std::vector vector_to_insert{4, 7, 3, -5}; vector_under_test.insert_at(0, vector_to_insert); - EXPECT_EQ(functional_vector({ 4, 7, 3, -5 }), vector_under_test); + EXPECT_EQ(vector({ 4, 7, 3, -5 }), vector_under_test); } -TEST(FunctionalVectorTest, InsertRangeExistingWrongInsertionIndexStdVector) +TEST(VectorTest, InsertRangeExistingWrongInsertionIndexStdVector) { - functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); const std::vector vector_to_insert({9, -5, 6}); EXPECT_DEATH(vector_under_test.insert_at(-1, vector_to_insert), ""); EXPECT_DEATH(vector_under_test.insert_at(10, vector_to_insert), ""); } -TEST(FunctionalVectorTest, InsertRangeExistingStdVector) +TEST(VectorTest, InsertRangeExistingStdVector) { - functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); const std::vector vector_to_insert({9, -5, 6}); vector_under_test.insert_at(3, vector_to_insert); - EXPECT_EQ(functional_vector({ 1, 4, 2, 9, -5, 6, 5, 8, 3, 1, 7, 1 }), vector_under_test); + EXPECT_EQ(vector({ 1, 4, 2, 9, -5, 6, 5, 8, 3, 1, 7, 1 }), vector_under_test); } -TEST(FunctionalVectorTest, InsertRangeEmptyInitializerList) +TEST(VectorTest, InsertRangeEmptyInitializerList) { - functional_vector vector_under_test; + vector vector_under_test; vector_under_test.insert_at(0, {4, 7, 3, -5}); - EXPECT_EQ(functional_vector({ 4, 7, 3, -5 }), vector_under_test); + EXPECT_EQ(vector({ 4, 7, 3, -5 }), vector_under_test); } -TEST(FunctionalVectorTest, InsertRangeExistingWrongInsertionIndexInitializerList) +TEST(VectorTest, InsertRangeExistingWrongInsertionIndexInitializerList) { - functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_DEATH(vector_under_test.insert_at(-1, { 9, -5, 6 }), ""); EXPECT_DEATH(vector_under_test.insert_at(10, { 9, -5, 6 }), ""); } -TEST(FunctionalVectorTest, InsertRangeExistingInitializerList) +TEST(VectorTest, InsertRangeExistingInitializerList) { - functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); vector_under_test.insert_at(3, {9, -5, 6}); - EXPECT_EQ(functional_vector({ 1, 4, 2, 9, -5, 6, 5, 8, 3, 1, 7, 1 }), vector_under_test); + EXPECT_EQ(vector({ 1, 4, 2, 9, -5, 6, 5, 8, 3, 1, 7, 1 }), vector_under_test); } -TEST(FunctionalVectorTest, InsertingRangeEmptyFunctionalVector) +TEST(VectorTest, InsertingRangeEmptyFunctionalVector) { - const functional_vector vector_under_test; - const functional_vector vector_to_insert({4, 7, 3, -5}); + const vector vector_under_test; + const vector vector_to_insert({4, 7, 3, -5}); const auto result_vector = vector_under_test.inserting_at(0, vector_to_insert); - EXPECT_EQ(functional_vector({ 4, 7, 3, -5 }), result_vector); + EXPECT_EQ(vector({ 4, 7, 3, -5 }), result_vector); } -TEST(FunctionalVectorTest, InsertingRangeExistingWrongInsertionIndexFunctionalVector) +TEST(VectorTest, InsertingRangeExistingWrongInsertionIndexFunctionalVector) { - const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); - const functional_vector vector_to_insert({9, -5, 6}); + const vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + const vector vector_to_insert({9, -5, 6}); EXPECT_DEATH(vector_under_test.inserting_at(-1, vector_to_insert), ""); EXPECT_DEATH(vector_under_test.inserting_at(10, vector_to_insert), ""); } -TEST(FunctionalVectorTest, InsertingRangeExistingFunctionalVector) +TEST(VectorTest, InsertingRangeExistingFunctionalVector) { - const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); - const functional_vector vector_to_insert({9, -5, 6}); + const vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + const vector vector_to_insert({9, -5, 6}); const auto result_vector = vector_under_test.inserting_at(3, vector_to_insert); - EXPECT_EQ(functional_vector({ 1, 4, 2, 9, -5, 6, 5, 8, 3, 1, 7, 1 }), result_vector); + EXPECT_EQ(vector({ 1, 4, 2, 9, -5, 6, 5, 8, 3, 1, 7, 1 }), result_vector); } -TEST(FunctionalVectorTest, InsertingRangeEmptyStdVector) +TEST(VectorTest, InsertingRangeEmptyStdVector) { - const functional_vector vector_under_test; + const vector vector_under_test; const std::vector vector_to_insert({4, 7, 3, -5}); const auto result_vector = vector_under_test.inserting_at(0, vector_to_insert); - EXPECT_EQ(functional_vector({ 4, 7, 3, -5 }), result_vector); + EXPECT_EQ(vector({ 4, 7, 3, -5 }), result_vector); } -TEST(FunctionalVectorTest, InsertingRangeExistingWrongInsertionIndexStdVector) +TEST(VectorTest, InsertingRangeExistingWrongInsertionIndexStdVector) { - const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + const vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); const std::vector vector_to_insert({9, -5, 6}); EXPECT_DEATH(vector_under_test.inserting_at(-1, vector_to_insert), ""); EXPECT_DEATH(vector_under_test.inserting_at(10, vector_to_insert), ""); } -TEST(FunctionalVectorTest, InsertingRangeExistingStdVector) +TEST(VectorTest, InsertingRangeExistingStdVector) { - const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + const vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); const std::vector vector_to_insert({9, -5, 6}); const auto result_vector = vector_under_test.inserting_at(3, vector_to_insert); - EXPECT_EQ(functional_vector({ 1, 4, 2, 9, -5, 6, 5, 8, 3, 1, 7, 1 }), result_vector); + EXPECT_EQ(vector({ 1, 4, 2, 9, -5, 6, 5, 8, 3, 1, 7, 1 }), result_vector); } -TEST(FunctionalVectorTest, InsertingRangeEmptyInitializerList) +TEST(VectorTest, InsertingRangeEmptyInitializerList) { - const functional_vector vector_under_test; + const vector vector_under_test; const auto result_vector = vector_under_test.inserting_at(0, {4, 7, 3, -5}); - EXPECT_EQ(functional_vector({ 4, 7, 3, -5 }), result_vector); + EXPECT_EQ(vector({ 4, 7, 3, -5 }), result_vector); } -TEST(FunctionalVectorTest, InsertingRangeExistingWrongInsertionIndexInitializerList) +TEST(VectorTest, InsertingRangeExistingWrongInsertionIndexInitializerList) { - const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + const vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_DEATH(vector_under_test.inserting_at(-1, { 9, -5, 6 }), ""); EXPECT_DEATH(vector_under_test.inserting_at(10, { 9, -5, 6 }), ""); } -TEST(FunctionalVectorTest, InsertingRangeExistingInitializerList) +TEST(VectorTest, InsertingRangeExistingInitializerList) { - const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + const vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); const auto result_vector = vector_under_test.inserting_at(3, {9, -5, 6}); - EXPECT_EQ(functional_vector({ 1, 4, 2, 9, -5, 6, 5, 8, 3, 1, 7, 1 }), result_vector); + EXPECT_EQ(vector({ 1, 4, 2, 9, -5, 6, 5, 8, 3, 1, 7, 1 }), result_vector); } -TEST(FunctionalVectorTest, RemoveIndexRangeWithInvalidRange) +TEST(VectorTest, RemoveIndexRangeWithInvalidRange) { - functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); vector_under_test.remove_range(index_range::invalid); - EXPECT_EQ(functional_vector({ 1, 4, 2, 5, 8, 3, 1, 7, 1 }), vector_under_test); + EXPECT_EQ(vector({ 1, 4, 2, 5, 8, 3, 1, 7, 1 }), vector_under_test); } -TEST(FunctionalVectorTest, RemoveIndexRangeEmptyVector) +TEST(VectorTest, RemoveIndexRangeEmptyVector) { - functional_vector vector_under_test; + vector vector_under_test; vector_under_test.remove_range(index_range::start_count(1, 12)); - EXPECT_EQ(functional_vector(), vector_under_test); + EXPECT_EQ(vector(), vector_under_test); } -TEST(FunctionalVectorTest, RemoveIndexRangeStartCountSuccess) +TEST(VectorTest, RemoveIndexRangeStartCountSuccess) { - functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); vector_under_test.remove_range(index_range::start_count(2, 3)); - EXPECT_EQ(functional_vector({ 1, 4, 3, 1, 7, 1 }), vector_under_test); + EXPECT_EQ(vector({ 1, 4, 3, 1, 7, 1 }), vector_under_test); } -TEST(FunctionalVectorTest, RemoveRangeStartEndSuccess) +TEST(VectorTest, RemoveRangeStartEndSuccess) { - functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); vector_under_test.remove_range(index_range::start_end(3, 6)); - EXPECT_EQ(functional_vector({ 1, 4, 2, 7, 1 }), vector_under_test); + EXPECT_EQ(vector({ 1, 4, 2, 7, 1 }), vector_under_test); } -TEST(FunctionalVectorTest, RemovingIndexRangeWithInvalidRange) +TEST(VectorTest, RemovingIndexRangeWithInvalidRange) { - const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + const vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); const auto shorter_vector = vector_under_test.removing_range(index_range::invalid); - EXPECT_EQ(functional_vector({ 1, 4, 2, 5, 8, 3, 1, 7, 1 }), shorter_vector); + EXPECT_EQ(vector({ 1, 4, 2, 5, 8, 3, 1, 7, 1 }), shorter_vector); } -TEST(FunctionalVectorTest, RemovingRangeEmptyVector) +TEST(VectorTest, RemovingRangeEmptyVector) { - const functional_vector vector_under_test; + const vector vector_under_test; const auto shorter_vector = vector_under_test.removing_range(index_range::start_count(1, 12)); - EXPECT_EQ(functional_vector(), shorter_vector); + EXPECT_EQ(vector(), shorter_vector); } -TEST(FunctionalVectorTest, RemovingIndexRangeStartCountSuccess) +TEST(VectorTest, RemovingIndexRangeStartCountSuccess) { - const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + const vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); const auto shorter_vector = vector_under_test.removing_range(index_range::start_count(2, 3)); - EXPECT_EQ(functional_vector({ 1, 4, 3, 1, 7, 1 }), shorter_vector); + EXPECT_EQ(vector({ 1, 4, 3, 1, 7, 1 }), shorter_vector); } -TEST(FunctionalVectorTest, RemovingIndexRangeStartEndSuccess) +TEST(VectorTest, RemovingIndexRangeStartEndSuccess) { - const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + const vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); const auto shorter_vector = vector_under_test.removing_range(index_range::start_end(3, 6)); - EXPECT_EQ(functional_vector({ 1, 4, 2, 7, 1 }), shorter_vector); + EXPECT_EQ(vector({ 1, 4, 2, 7, 1 }), shorter_vector); } -TEST(FunctionalVectorTest, ReplaceRangeAtWithEmptySource) +TEST(VectorTest, ReplaceRangeAtWithEmptySource) { - functional_vector vector_under_test({5, -3, 4, -9}); + vector vector_under_test({5, -3, 4, -9}); vector_under_test.replace_range_at(3, std::vector()); - EXPECT_EQ(functional_vector({ 5, -3 , 4, -9 }), vector_under_test); + EXPECT_EQ(vector({ 5, -3 , 4, -9 }), vector_under_test); } -TEST(FunctionalVectorTest, ReplaceRangeAtWrongIndex) +TEST(VectorTest, ReplaceRangeAtWrongIndex) { - functional_vector vector_under_test({5, -3, 4, -9}); + vector vector_under_test({5, -3, 4, -9}); EXPECT_DEATH(vector_under_test.replace_range_at(-1, { 1, 2, 6, 4 }), ""); EXPECT_DEATH(vector_under_test.replace_range_at(4, { 1, 2, 6, 4 }), ""); EXPECT_DEATH(vector_under_test.replace_range_at(5, { 1, 2, 6, 4 }), ""); } -TEST(FunctionalVectorTest, ReplaceRangeAtMoreElementsInSourceThanCapacity) +TEST(VectorTest, ReplaceRangeAtMoreElementsInSourceThanCapacity) { - functional_vector vector_under_test({5, -3, 4, -9}); + vector vector_under_test({5, -3, 4, -9}); EXPECT_DEATH(vector_under_test.replace_range_at(2, { 1, 2, 6, 4, 8, 9, -10 }), ""); } -TEST(FunctionalVectorTest, ReplaceRangeAtWithFunctionalVector) +TEST(VectorTest, ReplaceRangeAtWithFunctionalVector) { - functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); - vector_under_test.replace_range_at(4, functional_vector({9, -10, 8})); - EXPECT_EQ(functional_vector({ 1, 4, 2, 5, 9, -10, 8, 7, 1 }), vector_under_test); + vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + vector_under_test.replace_range_at(4, vector({9, -10, 8})); + EXPECT_EQ(vector({ 1, 4, 2, 5, 9, -10, 8, 7, 1 }), vector_under_test); } -TEST(FunctionalVectorTest, ReplaceRangeAtWithStdVector) +TEST(VectorTest, ReplaceRangeAtWithStdVector) { - functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); vector_under_test.replace_range_at(4, std::vector({9, -10, 8})); - EXPECT_EQ(functional_vector({ 1, 4, 2, 5, 9, -10, 8, 7, 1 }), vector_under_test); + EXPECT_EQ(vector({ 1, 4, 2, 5, 9, -10, 8, 7, 1 }), vector_under_test); } -TEST(FunctionalVectorTest, ReplaceRangeAtWithInitializerList) +TEST(VectorTest, ReplaceRangeAtWithInitializerList) { - functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); vector_under_test.replace_range_at(4, std::initializer_list({9, -10, 8})); - EXPECT_EQ(functional_vector({ 1, 4, 2, 5, 9, -10, 8, 7, 1 }), vector_under_test); + EXPECT_EQ(vector({ 1, 4, 2, 5, 9, -10, 8, 7, 1 }), vector_under_test); } -TEST(FunctionalVectorTest, ReplacingRangeAtWithEmptySource) +TEST(VectorTest, ReplacingRangeAtWithEmptySource) { - const functional_vector vector_under_test({5, -3, 4, -9}); + const vector vector_under_test({5, -3, 4, -9}); const auto replaced_vector = vector_under_test.replacing_range_at(3, std::vector()); - EXPECT_EQ(functional_vector({ 5, -3 , 4, -9 }), replaced_vector); + EXPECT_EQ(vector({ 5, -3 , 4, -9 }), replaced_vector); } -TEST(FunctionalVectorTest, ReplacingRangeAtWrongIndex) +TEST(VectorTest, ReplacingRangeAtWrongIndex) { - const functional_vector vector_under_test({5, -3, 4, -9}); + const vector vector_under_test({5, -3, 4, -9}); EXPECT_DEATH(vector_under_test.replacing_range_at(-1, { 1, 2, 6, 4 }), ""); EXPECT_DEATH(vector_under_test.replacing_range_at(4, { 1, 2, 6, 4 }), ""); EXPECT_DEATH(vector_under_test.replacing_range_at(5, { 1, 2, 6, 4 }), ""); } -TEST(FunctionalVectorTest, ReplacingRangeAtMoreElementsInSourceThanCapacity) +TEST(VectorTest, ReplacingRangeAtMoreElementsInSourceThanCapacity) { - const functional_vector vector_under_test({5, -3, 4, -9}); + const vector vector_under_test({5, -3, 4, -9}); EXPECT_DEATH(vector_under_test.replacing_range_at(2, { 1, 2, 6, 4, 8, 9, -10 }), ""); } -TEST(FunctionalVectorTest, ReplacingRangeAtWithFunctionalVector) +TEST(VectorTest, ReplacingRangeAtWithFunctionalVector) { - const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); - const auto replaced_vector = vector_under_test.replacing_range_at(4, functional_vector({9, -10, 8})); - EXPECT_EQ(functional_vector({ 1, 4, 2, 5, 9, -10, 8, 7, 1 }), replaced_vector); + const vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + const auto replaced_vector = vector_under_test.replacing_range_at(4, vector({9, -10, 8})); + EXPECT_EQ(vector({ 1, 4, 2, 5, 9, -10, 8, 7, 1 }), replaced_vector); } -TEST(FunctionalVectorTest, ReplacingRangeAtWithStdVector) +TEST(VectorTest, ReplacingRangeAtWithStdVector) { - const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + const vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); const auto replaced_vector = vector_under_test.replacing_range_at(4, std::vector({9, -10, 8})); - EXPECT_EQ(functional_vector({ 1, 4, 2, 5, 9, -10, 8, 7, 1 }), replaced_vector); + EXPECT_EQ(vector({ 1, 4, 2, 5, 9, -10, 8, 7, 1 }), replaced_vector); } -TEST(FunctionalVectorTest, ReplacingRangeAtWithInitializerList) +TEST(VectorTest, ReplacingRangeAtWithInitializerList) { - const functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + const vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); const auto replaced_vector = vector_under_test.replacing_range_at(4, std::initializer_list({9, -10, 8})); - EXPECT_EQ(functional_vector({ 1, 4, 2, 5, 9, -10, 8, 7, 1 }), replaced_vector); + EXPECT_EQ(vector({ 1, 4, 2, 5, 9, -10, 8, 7, 1 }), replaced_vector); } -TEST(FunctionalVectorTest, Fill) +TEST(VectorTest, Fill) { - functional_vector vector_under_test({1, 3, -6, 4, -9}); + vector vector_under_test({1, 3, -6, 4, -9}); vector_under_test.fill(7); - EXPECT_EQ(functional_vector({ 7, 7, 7, 7, 7 }), vector_under_test); + EXPECT_EQ(vector({ 7, 7, 7, 7, 7 }), vector_under_test); } -TEST(FunctionalVectorTest, RepeatingConstructor) +TEST(VectorTest, RepeatingConstructor) { - const functional_vector vector_under_test(3, "John"); - EXPECT_EQ(functional_vector({ "John", "John", "John" }), vector_under_test); + const vector vector_under_test(3, "John"); + EXPECT_EQ(vector({ "John", "John", "John" }), vector_under_test); } -TEST(FunctionalVectorTest, EqualityOperatorEmptyVectors) +TEST(VectorTest, EqualityOperatorEmptyVectors) { - const functional_vector vec1; - const functional_vector vec2; + const vector vec1; + const vector vec2; EXPECT_TRUE(vec1 == vec2); EXPECT_FALSE(vec1 != vec2); } -TEST(FunctionalVectorTest, EqualityOperatorUnequalSizes) +TEST(VectorTest, EqualityOperatorUnequalSizes) { - const functional_vector vec1({1, 2, 3}); - const functional_vector vec2({1, 2, 3, 4}); + const vector vec1({1, 2, 3}); + const vector vec2({1, 2, 3, 4}); EXPECT_TRUE(vec1 != vec2); EXPECT_FALSE(vec1 == vec2); } -TEST(FunctionalVectorTest, EqualityOperatorEqualSizesDifferentElements) +TEST(VectorTest, EqualityOperatorEqualSizesDifferentElements) { - const functional_vector vec1({1, 2, 3}); - const functional_vector vec2({1, 2, 4}); + const vector vec1({1, 2, 3}); + const vector vec2({1, 2, 4}); EXPECT_TRUE(vec1 != vec2); EXPECT_FALSE(vec1 == vec2); } -TEST(FunctionalVectorTest, EqualityOperatorEqualVectors) +TEST(VectorTest, EqualityOperatorEqualVectors) { - const functional_vector vec1({1, 2, 3}); - const functional_vector vec2({1, 2, 3}); + const vector vec1({1, 2, 3}); + const vector vec2({1, 2, 3}); EXPECT_TRUE(vec1 == vec2); EXPECT_FALSE(vec1 != vec2); } -TEST(FunctionalVectorTest, EqualityOperatorCustomTypeEqualVectors) +TEST(VectorTest, EqualityOperatorCustomTypeEqualVectors) { - const functional_vector vec1({ + const vector vec1({ person(15, "Jake"), person(18, "Jannet"), person(25, "Kate") }); - const functional_vector vec2({ + const vector vec2({ person(15, "Jake"), person(18, "Jannet"), person(25, "Kate") @@ -1137,15 +1137,15 @@ TEST(FunctionalVectorTest, EqualityOperatorCustomTypeEqualVectors) EXPECT_FALSE(vec1 != vec2); } -TEST(FunctionalVectorTest, EqualityOperatorCustomTypeUnequalSizes) +TEST(VectorTest, EqualityOperatorCustomTypeUnequalSizes) { - const functional_vector vec1({ + const vector vec1({ person(15, "Jake"), person(18, "Jannet"), person(25, "Kate") }); - const functional_vector vec2({ + const vector vec2({ person(15, "Jake"), person(18, "Jannet"), person(25, "Kate"), @@ -1156,15 +1156,15 @@ TEST(FunctionalVectorTest, EqualityOperatorCustomTypeUnequalSizes) EXPECT_TRUE(vec1 != vec2); } -TEST(FunctionalVectorTest, EqualityOperatorCustomTypeUnequalVectors) +TEST(VectorTest, EqualityOperatorCustomTypeUnequalVectors) { - const functional_vector vec1({ + const vector vec1({ person(15, "Jake"), person(18, "Jannet"), person(25, "Kate") }); - const functional_vector vec2({ + const vector vec2({ person(15, "Jake"), person(53, "Bob"), person(35, "Suzan") @@ -1174,27 +1174,27 @@ TEST(FunctionalVectorTest, EqualityOperatorCustomTypeUnequalVectors) EXPECT_TRUE(vec1 != vec2); } -TEST(FunctionalVectorTest, ClearEmptyVector) +TEST(VectorTest, ClearEmptyVector) { - functional_vector vector_under_test; + vector vector_under_test; EXPECT_TRUE(vector_under_test.is_empty()); vector_under_test.clear(); EXPECT_EQ(0, vector_under_test.size()); EXPECT_TRUE(vector_under_test.is_empty()); } -TEST(FunctionalVectorTest, ClearFilledVector) +TEST(VectorTest, ClearFilledVector) { - functional_vector vector_under_test({5, -3, 4, -9}); + vector vector_under_test({5, -3, 4, -9}); EXPECT_FALSE(vector_under_test.is_empty()); vector_under_test.clear(); EXPECT_EQ(0, vector_under_test.size()); EXPECT_TRUE(vector_under_test.is_empty()); } -TEST(FunctionalVectorTest, CapacityReserveClear) +TEST(VectorTest, CapacityReserveClear) { - functional_vector vector_under_test; + vector vector_under_test; EXPECT_EQ(0, vector_under_test.capacity()); EXPECT_EQ(0, vector_under_test.size()); @@ -1211,36 +1211,36 @@ TEST(FunctionalVectorTest, CapacityReserveClear) EXPECT_EQ(0, vector_under_test.size()); } -TEST(FunctionalVectorTest, ResizeEmptyVector) +TEST(VectorTest, ResizeEmptyVector) { - functional_vector vector_under_test; + vector vector_under_test; vector_under_test.resize(5); - EXPECT_EQ(functional_vector({ 0, 0, 0, 0, 0 }), vector_under_test); + EXPECT_EQ(vector({ 0, 0, 0, 0, 0 }), vector_under_test); EXPECT_EQ(5, vector_under_test.capacity()); EXPECT_EQ(5, vector_under_test.size()); } -TEST(FunctionalVectorTest, ResizeSmallerThanCurrentSize) +TEST(VectorTest, ResizeSmallerThanCurrentSize) { - functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_EQ(9, vector_under_test.capacity()); EXPECT_EQ(9, vector_under_test.size()); vector_under_test.resize(5); - EXPECT_EQ(functional_vector({1, 4, 2, 5, 8}), vector_under_test); + EXPECT_EQ(vector({1, 4, 2, 5, 8}), vector_under_test); EXPECT_EQ(9, vector_under_test.capacity()); EXPECT_EQ(5, vector_under_test.size()); } -TEST(FunctionalVectorTest, AllOfFalse) +TEST(VectorTest, AllOfFalse) { - functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_FALSE(vector_under_test.all_of([](const int& number) { return number > 5; })); } -TEST(FunctionalVectorTest, AllOfTrue) +TEST(VectorTest, AllOfTrue) { - functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); vector_under_test.all_of([](const int& number) { return number < 10; }); @@ -1248,13 +1248,13 @@ TEST(FunctionalVectorTest, AllOfTrue) } #ifdef PARALLEL_ALGORITHM_AVAILABLE -TEST(FunctionalVectorTest, AllOfParallelFalse) +TEST(VectorTest, AllOfParallelFalse) { functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_FALSE(vector_under_test.all_of_parallel([](const int& number) { return number > 5; })); } -TEST(FunctionalVectorTest, AllOfParallelTrue) +TEST(VectorTest, AllOfParallelTrue) { functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); vector_under_test.all_of([](const int& number) { @@ -1264,58 +1264,58 @@ TEST(FunctionalVectorTest, AllOfParallelTrue) } #endif -TEST(FunctionalVectorTest, AnyOfFalse) +TEST(VectorTest, AnyOfFalse) { - functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_FALSE(vector_under_test.any_of([](const int& number) { return number > 20; })); } -TEST(FunctionalVectorTest, AnyOfTrue) +TEST(VectorTest, AnyOfTrue) { - functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_TRUE(vector_under_test.any_of([](const int& number) { return number >= 7; })); } #ifdef PARALLEL_ALGORITHM_AVAILABLE -TEST(FunctionalVectorTest, AnyOfParallelFalse) +TEST(VectorTest, AnyOfParallelFalse) { functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_FALSE(vector_under_test.any_of_parallel([](const int& number) { return number > 20; })); } -TEST(FunctionalVectorTest, AnyOfParallelTrue) +TEST(VectorTest, AnyOfParallelTrue) { functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_TRUE(vector_under_test.any_of_parallel([](const int& number) { return number >= 7; })); } #endif -TEST(FunctionalVectorTest, NoneOfFalse) +TEST(VectorTest, NoneOfFalse) { - functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_FALSE(vector_under_test.none_of([](const int& number) { return number > 7; })); } -TEST(FunctionalVectorTest, NoneOfTrue) +TEST(VectorTest, NoneOfTrue) { - functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_TRUE(vector_under_test.none_of([](const int& number) { return number < -2; })); } #ifdef PARALLEL_ALGORITHM_AVAILABLE -TEST(FunctionalVectorTest, NoneOfParallelFalse) +TEST(VectorTest, NoneOfParallelFalse) { functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_FALSE(vector_under_test.none_of_parallel([](const int& number) { return number > 7; })); } -TEST(FunctionalVectorTest, NoneOfParallelTrue) +TEST(VectorTest, NoneOfParallelTrue) { functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_TRUE(vector_under_test.none_of_parallel([](const int& number) { return number < -2; })); } -TEST(FunctionalVectorTest, ForEachParallel) +TEST(VectorTest, ForEachParallel) { functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_EQ(9, vector_under_test.size()); @@ -1325,16 +1325,16 @@ TEST(FunctionalVectorTest, ForEachParallel) } #endif -TEST(FunctionalVectorTest, Distinct) +TEST(VectorTest, Distinct) { - const functional_vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); + const vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); const auto& unique_numbers = numbers.distinct(); - EXPECT_EQ(functional_set({1, 2, 3, 4, 5, 7, 8}), unique_numbers); + EXPECT_EQ(set({1, 2, 3, 4, 5, 7, 8}), unique_numbers); } -TEST(FunctionalVectorTest, DistinctCustomType) +TEST(VectorTest, DistinctCustomType) { - const functional_vector persons({ + const vector persons({ person(15, "Jake"), person(15, "Jake"), person(18, "Jannet"), @@ -1345,7 +1345,7 @@ TEST(FunctionalVectorTest, DistinctCustomType) const auto& unique_persons = persons.distinct(); - const functional_set expected({ + const set expected({ person(15, "Jake"), person(18, "Jannet"), person(25, "Kate"), From 1a678f347d6d646dd90dd6f5f45c3a2bd60ab12a Mon Sep 17 00:00:00 2001 From: jkaliak Date: Thu, 14 Jul 2022 21:34:15 +0200 Subject: [PATCH 39/44] optional_t in fcpp namespace for C++17 and function documentation --- include/optional.h | 7 +- include/set.h | 96 +++++++------- include/vector.h | 318 ++++++++++++++++++++++----------------------- 3 files changed, 211 insertions(+), 210 deletions(-) diff --git a/include/optional.h b/include/optional.h index 805d08f..cea05b7 100644 --- a/include/optional.h +++ b/include/optional.h @@ -24,6 +24,8 @@ #pragma once #include "compatibility.h" +namespace fcpp { + #ifdef CPP17_AVAILABLE #include template @@ -32,8 +34,6 @@ using optional_t = std::optional; #include #include -namespace fcpp { - // A replacement for std::optional when C++17 is not available template class optional { @@ -99,5 +99,6 @@ class optional { template using optional_t = optional; -} #endif + +} diff --git a/include/set.h b/include/set.h index 50c14bd..1f3df2e 100644 --- a/include/set.h +++ b/include/set.h @@ -70,12 +70,12 @@ class set // the difference is the operation A – B = {x : x ∈ A and x ∉ B} // // example: - // const functional_set set1(std::set({1, 2, 3, 5, 7, 8, 10})); - // const functional_set set2(std::set({2, 5, 7, 10, 15, 17})); + // const fcpp::set set1(std::set({1, 2, 3, 5, 7, 8, 10})); + // const fcpp::set set2(std::set({2, 5, 7, 10, 15, 17})); // const auto& diff = set1.difference(set2); // // outcome: - // diff -> functional_set({1, 3, 8}) + // diff -> fcpp::set({1, 3, 8}) [[nodiscard]] set difference_with(const set& other) const { std::set diff; std::set_difference(begin(), @@ -95,12 +95,12 @@ class set // the union is the operation A ∪ B = {x : x ∈ A or x ∈ B} // // example: - // const functional_set set1(std::set({1, 2, 3, 5, 7, 8, 10})); - // const functional_set set2(std::set({2, 5, 7, 10, 15, 17})); + // const fcpp::set set1(std::set({1, 2, 3, 5, 7, 8, 10})); + // const fcpp::set set2(std::set({2, 5, 7, 10, 15, 17})); // const auto& combined = set1.set_union(set2); // // outcome: - // combined -> functional_set({1, 2, 3, 5, 7, 8, 10, 15, 17}) + // combined -> fcpp::set({1, 2, 3, 5, 7, 8, 10, 15, 17}) [[nodiscard]] set union_with(const set& other) const { std::set combined; std::set_union(begin(), @@ -120,12 +120,12 @@ class set // the intersection is the operation A ∩ B = {x : x ∈ A and x ∈ B} // // example: - // const functional_set set1(std::set({1, 2, 3, 5, 7, 8, 10})); - // const functional_set set2(std::set({2, 5, 7, 10, 15, 17})); + // const fcpp::set set1(std::set({1, 2, 3, 5, 7, 8, 10})); + // const fcpp::set set2(std::set({2, 5, 7, 10, 15, 17})); // const auto& combined = set1.set_union(set2); // // outcome: - // combined -> functional_set({2, 5, 7, 10}) + // combined -> fcpp::set({2, 5, 7, 10}) [[nodiscard]] set intersect_with(const set& other) const { std::set intersection; std::set_intersection(begin(), @@ -143,11 +143,11 @@ class set // Returns the minimum key in the set, if it's not empty. // // example: - // const functional_set numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); + // const fcpp::set numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); // auto minimum = numbers.min(); // // // an empty's set minimum value - // functional_set().min().has_value() // false + // fcpp::set().min().has_value() // false // // outcome: // minimum.has_value() -> true @@ -163,11 +163,11 @@ class set // Returns the maximum key in the set, if it's not empty. // // example: - // const functional_set numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); + // const fcpp::set numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); // auto maximum = numbers.max(); // // // an empty's set maximum value - // functional_set().max().has_value() // false + // fcpp::set().max().has_value() // false // // outcome: // maximum.has_value() -> true @@ -190,11 +190,11 @@ class set // }); // // outcome: - // output_set -> functional_set({ "-5", "1", "3" }) + // output_set -> fcpp::set({ "-5", "1", "3" }) // // is equivalent to: - // const functional_set input_set({ 1, 3, -5 }); - // functional_set output_set; + // const fcpp::set input_set({ 1, 3, -5 }); + // fcpp::set output_set; // for (auto const& key: input_set) { // output_set.insert(std::to_string(key)); // } @@ -215,7 +215,7 @@ class set // Returns true if all keys match the predicate (return true) // // example: - // const functional_set numbers({1, 4, 2, 5, 8, 3}); + // const fcpp::set numbers({1, 4, 2, 5, 8, 3}); // // // returns true // numbers.all_of([](const int &number) { @@ -241,7 +241,7 @@ class set // Returns true if at least one key match the predicate (returns true) // // example: - // const functional_set numbers({1, 4, 2, 5, 8, 3}); + // const fcpp::set numbers({1, 4, 2, 5, 8, 3}); // // // returns true // numbers.any_of([](const int &number) { @@ -267,7 +267,7 @@ class set // Returns true if none of the keys match the predicate (all return false) // // example: - // const functional_set numbers({1, 4, 2, 5, 8, 3}); + // const fcpp::set numbers({1, 4, 2, 5, 8, 3}); // // // returns true // numbers.none_of([](const int &number) { @@ -294,16 +294,16 @@ class set // which match the given predicate are kept (mutating) // // example: - // functional_set numbers({ 1, 3, -5, 2, -1, 9, -4 }); + // fcpp::set numbers({ 1, 3, -5, 2, -1, 9, -4 }); // numbers.filter([](const int& element) { // return element >= 1.5; // }); // // outcome: - // numbers -> functional_set({ 2, 3, 9 }); + // numbers -> fcpp::set({ 2, 3, 9 }); // // is equivalent to: - // functional_set numbers({ 1, 3, -5, 2, -1, 9, -4 }); + // fcpp::set numbers({ 1, 3, -5, 2, -1, 9, -4 }); // for (auto i = 0; i < numbers.size(); ++i) { // if (numbers[i] >= 1.5) { // continue; @@ -333,14 +333,14 @@ class set // of the copy which match the given predicate are kept (non-mutating) // // example: - // const functional_set numbers({ 1, 3, -5, 2, -1, 9, -4 }); + // const fcpp::set numbers({ 1, 3, -5, 2, -1, 9, -4 }); // auto filtered_numbers = numbers.filtered([](const int& element) { // return element >= 1.5; // }); // // outcome: - // filtered_numbers -> functional_set({ 2, 3, 9 }); - // numbers -> functional_set({ 1, 3, -5, 2, -1, 9, -4 }); + // filtered_numbers -> fcpp::set({ 2, 3, 9 }); + // numbers -> fcpp::set({ 1, 3, -5, 2, -1, 9, -4 }); #ifdef CPP17_AVAILABLE template >> #else @@ -373,12 +373,12 @@ class set // The sizes of the two sets must be equal. // // example: - // const functional_set ages({ 25, 45, 30, 63 }); - // const functional_set persons({ "Jake", "Bob", "Michael", "Philipp" }); + // const fcpp::set ages({ 25, 45, 30, 63 }); + // const fcpp::set persons({ "Jake", "Bob", "Michael", "Philipp" }); // const auto zipped = ages.zip(persons); // // outcome: - // zipped -> functional_set>({ + // zipped -> fcpp::set>({ // std::pair(25, "Bob"), // std::pair(30, "Jake"), // std::pair(45, "Michael"), @@ -396,7 +396,7 @@ class set // Performs the functional `zip` algorithm. // The number of keys must match the set's size. - // For more details, see the zip function which accepts a functional_set as input. + // For more details, see the zip function which accepts a fcpp::set as input. template [[nodiscard]] set> zip(const std::set& set) const { @@ -405,7 +405,7 @@ class set // Performs the functional `zip` algorithm by using the unique values of the vector. // The number of uniques vector values must match the set's size. - // For more details, see the zip function which accepts a functional_set as input. + // For more details, see the zip function which accepts a fcpp::set as input. template [[nodiscard]] set> zip(const vector& vector) const { @@ -415,7 +415,7 @@ class set // Performs the functional `zip` algorithm by using the unique values of the vector. // The number of uniques vector values must match the set's size. - // For more details, see the zip function which accepts a functional_set as input. + // For more details, see the zip function which accepts a fcpp::set as input. template [[nodiscard]] set> zip(const std::vector& vector) const { @@ -440,11 +440,11 @@ class set // Removes an element from the set, if it exists, potentially changing the set's contents (mutating) // // example: - // functional_set numbers({1, 4, 2}); + // fcpp::set numbers({1, 4, 2}); // numbers.remove(4); // // outcome: - // numbers -> functional_set({1, 2}) + // numbers -> fcpp::set({1, 2}) set& remove(const TKey& element) { backing_set_.erase(element); @@ -454,12 +454,12 @@ class set // Returns a copy by removing an element from the set, if it exists (non-mutating) // // example: - // const functional_set numbers({1, 4, 2}); + // const fcpp::set numbers({1, 4, 2}); // auto less_numbers = numbers.removing(4); // // outcome: - // less_numbers -> functional_set({1, 2}) - // numbers -> functional_set({1, 2, 4}) + // less_numbers -> fcpp::set({1, 2}) + // numbers -> fcpp::set({1, 2, 4}) [[nodiscard]] set removing(const TKey& element) const { auto copy(backing_set_); @@ -470,11 +470,11 @@ class set // Inserts an element in the set, if it does not already exist, potentially changing the set's contents (mutating) // // example: - // functional_set numbers({1, 4, 2}); + // fcpp::set numbers({1, 4, 2}); // numbers.insert(18); // // outcome: - // numbers -> functional_set({1, 2, 4, 18}) + // numbers -> fcpp::set({1, 2, 4, 18}) set& insert(const TKey& element) { backing_set_.insert(element); @@ -484,12 +484,12 @@ class set // Returns a copy by inserting an element in the set, if it does not already exist (non-mutating) // // example: - // const functional_set numbers({1, 4, 2}); + // const fcpp::set numbers({1, 4, 2}); // auto augmented_numbers = numbers.inserting(18); // // outcome: - // augmented_numbers -> functional_set({1, 2, 4, 18}) - // numbers -> functional_set({1, 2, 4}) + // augmented_numbers -> fcpp::set({1, 2, 4, 18}) + // numbers -> fcpp::set({1, 2, 4}) [[nodiscard]] set inserting(const TKey& element) const { auto copy(backing_set_); @@ -500,11 +500,11 @@ class set // Removes all keys from the set (mutating) // // example: - // functional_set numbers({1, 4, 2}); + // fcpp::set numbers({1, 4, 2}); // numbers.clear(); // // outcome: - // numbers -> functional_set({}) + // numbers -> fcpp::set({}) set& clear() { backing_set_.clear(); @@ -514,12 +514,12 @@ class set // Returns a new set by clearing all keys from the current set (non-mutating) // // example: - // const functional_set numbers({1, 4, 2}); + // const fcpp::set numbers({1, 4, 2}); // auto cleared_numbers = numbers.clearing(); // // outcome: - // cleared_numbers -> functional_set({}) - // numbers -> functional_set numbers({1, 4, 2}) + // cleared_numbers -> fcpp::set({}) + // numbers -> fcpp::set numbers({1, 4, 2}) [[nodiscard]] set clearing() const { return set(); @@ -528,7 +528,7 @@ class set // Returns true if the key is present in the set, otherwise false // // example: - // const functional_set numbers({1, 4, 2}); + // const fcpp::set numbers({1, 4, 2}); // numbers.contains(1); // true // numbers.contains(15); // false [[nodiscard]] bool contains(const TKey& key) const @@ -652,7 +652,7 @@ class set #ifdef CPP17_AVAILABLE template::value>> [[nodiscard]] auto zip_impl( const Iterator& set_begin, const Iterator& set_end) const -> - functional_set>> + set>> { using UKey = deref_type; #else diff --git a/include/vector.h b/include/vector.h index 7925acb..2cbc0f1 100644 --- a/include/vector.h +++ b/include/vector.h @@ -68,10 +68,10 @@ class vector // Creates a new vector by repeating a given element. // // example: - // const functional_vector filled_vector(3, "John"); + // const fcpp::vector filled_vector(3, "John"); // // outcome: - // filled_vector -> functional_vector({ "John", "John", "John" }) + // filled_vector -> fcpp::vector({ "John", "John", "John" }) explicit vector(size_t count, const T& element) : backing_vector_(count, element) { @@ -81,17 +81,17 @@ class vector // output of applying the transform function on every element of this instance. // // example: - // const functional_vector input_vector({ 1, 3, -5 }); + // const fcpp::vector input_vector({ 1, 3, -5 }); // const auto output_vector = input_vector.map([](const auto& element) { // return std::to_string(element); // }); // // outcome: - // output_vector -> functional_vector({ "1", "3", "-5" }) + // output_vector -> fcpp::vector({ "1", "3", "-5" }) // // is equivalent to: - // const functional_vector input_vector({ 1, 3, -5 }); - // functional_vector output_vector; + // const fcpp::vector input_vector({ 1, 3, -5 }); + // fcpp::vector output_vector; // for (auto i = 0; i < input_vector.size(); ++i) { // output_vector.insert_back(std::to_string(input_vector[i])); // } @@ -115,7 +115,7 @@ class vector // Performs the functional `map` algorithm in parallel. // See also the sequential version for more documentation. template >> - functional_vector map_parallel(Transform && transform) const + vector map_parallel(Transform && transform) const { std::vector transformed_vector; transformed_vector.resize(backing_vector_.size()); @@ -124,14 +124,14 @@ class vector backing_vector_.cend(), transformed_vector.begin(), std::forward(transform)); - return functional_vector(transformed_vector); + return vector(transformed_vector); } #endif // Returns true if all elements match the predicate (return true) // // example: - // functional_vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); + // fcpp::vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); // // // returns true // numbers.all_of([](const auto &number) { @@ -170,7 +170,7 @@ class vector // Returns true if at least one of the elements matches the predicate (returns true) // // example: - // functional_vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); + // fcpp::vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); // // // returns true // numbers.any_of([](const auto &number) { @@ -209,7 +209,7 @@ class vector // Returns true if no element matches the predicate (all return false) // // example: - // functional_vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); + // fcpp::vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); // // // returns true // numbers.none_of([](const auto &number) { @@ -249,16 +249,16 @@ class vector // which match the given predicate are kept (mutating) // // example: - // functional_vector numbers({ 1, 3, -5, 2, -1, 9, -4 }); + // fcpp::vector numbers({ 1, 3, -5, 2, -1, 9, -4 }); // numbers.filter([](const auto& element) { // return element >= 1.5; // }); // // outcome: - // numbers -> functional_vector({ 3, 2, 9 }); + // numbers -> fcpp::vector({ 3, 2, 9 }); // // is equivalent to: - // functional_vector numbers({ 1, 3, -5, 2, -1, 9, -4 }); + // fcpp::vector numbers({ 1, 3, -5, 2, -1, 9, -4 }); // for (auto i = 0; i < numbers.size(); ++i) { // if (numbers[i] >= 1.5) { // continue; @@ -285,7 +285,7 @@ class vector // Performs the functional `filter` algorithm in parallel. // See also the sequential version for more documentation. template >> - functional_vector& filter_parallel(Filter && predicate_to_keep) + vector& filter_parallel(Filter && predicate_to_keep) { backing_vector_.erase(std::remove_if(std::execution::par, backing_vector_.begin(), @@ -301,18 +301,18 @@ class vector // the copy which match the given predicate are kept (non-mutating) // // example: - // const functional_vector numbers({ 1, 3, -5, 2, -1, 9, -4 }); + // const fcpp::vector numbers({ 1, 3, -5, 2, -1, 9, -4 }); // const auto filtered_numbers = numbers.filtered([](const auto& element) { // return element >= 1.5; // }); // // outcome: - // numbers -> functional_vector({ 1, 3, -5, 2, -1, 9, -4 }) - // filtered_numbers -> functional_vector({ 3, 2, 9 }) + // numbers -> fcpp::vector({ 1, 3, -5, 2, -1, 9, -4 }) + // filtered_numbers -> fcpp::vector({ 3, 2, 9 }) // // is equivalent to: - // const functional_vector numbers({ 1, 3, -5, 2, -1, 9, -4 }); - // functional_vector filtered_numbers; + // const fcpp::vector numbers({ 1, 3, -5, 2, -1, 9, -4 }); + // fcpp::vector filtered_numbers; // for (auto i = 0; i < numbers.size(); ++i) { // if (numbers[i] >= 1.5) { // filtered_numbers.insert_back(numbers[i]); @@ -338,7 +338,7 @@ class vector // Performs the `filtered` algorithm in parallel. // See also the sequential version for more documentation. template >> - functional_vector filtered_parallel(Callable && predicate_to_keep) const + vector filtered_parallel(Callable && predicate_to_keep) const { #ifdef _MSC_VER // Visual Studio compiler is stricter than GCC in its use of iterators, so back_inserter wouldn't work here @@ -353,7 +353,7 @@ class vector backing_vector_.end(), std::back_inserter(filtered_vector), std::forward(predicate_to_keep)); - return functional_vector(filtered_vector); + return vector(filtered_vector); #endif } #endif @@ -361,11 +361,11 @@ class vector // Reverses the order of the elements in place (mutating) // // example: - // functional_vector numbers_vector({ 1, 3, -5, 2, -1, 9, -4 }); + // fcpp::vector numbers_vector({ 1, 3, -5, 2, -1, 9, -4 }); // numbers_vector.reverse(); // // outcome: - // numbers_vector -> functional_vector({ -4, 9, -1, 2, -5, 3, 1 }) + // numbers_vector -> fcpp::vector({ -4, 9, -1, 2, -5, 3, 1 }) vector& reverse() { std::reverse(backing_vector_.begin(), backing_vector_.end()); @@ -375,12 +375,12 @@ class vector // Returns a copy of this instance, whose elements are in reverse order (non-mutating) // // example: - // const functional_vector input_vector({ 1, 3, -5, 2, -1, 9, -4 }); + // const fcpp::vector input_vector({ 1, 3, -5, 2, -1, 9, -4 }); // const auto reversed_vector = input_vector.reversed(); // // outcome: - // input_vector -> functional_vector({ 1, 3, -5, 2, -1, 9, -4 }); - // reversed_vector -> functional_vector({ -4, 9, -1, 2, -5, 3, 1 }) + // input_vector -> fcpp::vector({ 1, 3, -5, 2, -1, 9, -4 }); + // reversed_vector -> fcpp::vector({ -4, 9, -1, 2, -5, 3, 1 }) [[nodiscard]] vector reversed() const { std::vector reversed_vector(backing_vector_.crbegin(), backing_vector_.crend()); @@ -402,23 +402,23 @@ class vector // index. The sizes of the two vectors must be equal. // // example: - // const functional_vector ages_vector({32, 25, 53}); - // const functional_vector names_vector({"Jake", "Mary", "John"}); + // const fcpp::vector ages_vector({32, 25, 53}); + // const fcpp::vector names_vector({"Jake", "Mary", "John"}); // const auto zipped_vector = ages_vector.zip(names_vector); // // outcome: - // zipped_vector -> functional_vector>({ + // zipped_vector -> fcpp::vector>({ // (32, "Jake"), // (25, "Mary"), // (53, "John"), // }) // // is equivalent to: - // const functional_vector ages_vector({32, 25, 53}); - // const functional_vector names_vector({"Jake", "Mary", "John"}); - // functional_vector> zipped_vector; + // const fcpp::vector ages_vector({32, 25, 53}); + // const fcpp::vector names_vector({"Jake", "Mary", "John"}); + // fcpp::vector> zipped_vector; // for (auto i = 0; i < ages_vector.size(); ++i) { - // functional_vector::pair tuple; + // fcpp::vector::pair tuple; // tuple.first = ages_vector[i]; // tuple.second = names_vector[i]; // zipped_vector.insert_back(tuple); @@ -438,23 +438,23 @@ class vector // index. The sizes of the two vectors must be equal. // // example: - // const functional_vector ages_vector({32, 25, 53}); + // const fcpp::vector ages_vector({32, 25, 53}); // const std::vector names_vector({"Jake", "Mary", "John"}); // const auto zipped_vector = ages_vector.zip(names_vector); // // outcome: - // zipped_vector -> functional_vector>({ + // zipped_vector -> fcpp::vector>({ // (32, "Jake"), // (25, "Mary"), // (53, "John"), // }) // // is equivalent to: - // const functional_vector ages_vector({32, 25, 53}); + // const fcpp::vector ages_vector({32, 25, 53}); // const std::vector names_vector({"Jake", "Mary", "John"}); - // functional_vector> zipped_vector; + // fcpp::vector> zipped_vector; // for (auto i = 0; i < ages_vector.size(); ++i) { - // functional_vector::pair tuple; + // fcpp::vector::pair tuple; // tuple.first = ages_vector[i]; // tuple.second = names_vector[i]; // zipped_vector.insert_back(tuple); @@ -470,23 +470,23 @@ class vector } // example: - // const functional_vector ages_vector({32, 25, 53}); + // const fcpp::vector ages_vector({32, 25, 53}); // const std::initializer_list names_vector({"Jake", "Mary", "John"}); // const auto zipped_vector = ages_vector.zip(names_vector); // // outcome: - // zipped_vector -> functional_vector>({ + // zipped_vector -> fcpp::vector>({ // (32, "Jake"), // (25, "Mary"), // (53, "John"), // }) // // is equivalent to: - // const functional_vector ages_vector({32, 25, 53}); + // const fcpp::vector ages_vector({32, 25, 53}); // const std::initializer_list names_vector({"Jake", "Mary", "John"}); - // functional_vector> zipped_vector; + // fcpp::vector> zipped_vector; // for (auto i = 0; i < ages_vector.size(); ++i) { - // functional_vector::pair tuple; + // fcpp::vector::pair tuple; // tuple.first = ages_vector[i]; // tuple.second = names_vector[i]; // zipped_vector.insert_back(tuple); @@ -511,7 +511,7 @@ class vector // std::string name; // }; // ... - // functional_vector persons_vector({ + // fcpp::vector persons_vector({ // person(45, "Jake"), person(34, "Bob"), person(52, "Manfred"), person(8, "Alice") // }); // persons_vector.sort([](const auto& person1, const auto& person2) { @@ -519,7 +519,7 @@ class vector // }); // // outcome: - // person_vector -> functional_vector({ + // person_vector -> fcpp::vector({ // person(8, "Alice"), person(34, "Bob"), person(45, "Jake"), person(52, "Manfred") // }); #ifdef CPP17_AVAILABLE @@ -539,7 +539,7 @@ class vector // Performs the `sort` algorithm in parallel. // See also the sequential version for more documentation. template >> - functional_vector& sort_parallel(Sortable && comparison_predicate) + vector& sort_parallel(Sortable && comparison_predicate) { std::sort(std::execution::par, backing_vector_.begin(), @@ -552,11 +552,11 @@ class vector // Sorts the vector in place in ascending order, when its elements support comparison by std::less_equal [<=] (mutating). // // example: - // functional_vector numbers({3, 1, 9, -4}); + // fcpp::vector numbers({3, 1, 9, -4}); // numbers.sort_ascending(); // // outcome: - // numbers -> functional_vector({-4, 1, 3, 9}); + // numbers -> fcpp::vector({-4, 1, 3, 9}); vector& sort_ascending() { return sort(std::less_equal()); @@ -565,7 +565,7 @@ class vector #ifdef PARALLEL_ALGORITHM_AVAILABLE // Performs the `sort_ascending` algorithm in parallel. // See also the sequential version for more documentation. - functional_vector& sort_ascending_parallel() + vector& sort_ascending_parallel() { return sort_parallel(std::less_equal()); } @@ -574,11 +574,11 @@ class vector // Sorts the vector in place in descending order, when its elements support comparison by std::greater_equal [>=] (mutating). // // example: - // functional_vector numbers({3, 1, 9, -4}); + // fcpp::vector numbers({3, 1, 9, -4}); // numbers.sort_ascending(); // // outcome: - // numbers -> functional_vector({9, 3, 1, -4}); + // numbers -> fcpp::vector({9, 3, 1, -4}); vector& sort_descending() { return sort(std::greater_equal()); @@ -587,7 +587,7 @@ class vector #ifdef PARALLEL_ALGORITHM_AVAILABLE // Performs the `sort_ascending` algorithm in parallel. // See also the sequential version for more documentation. - functional_vector& sort_descending_parallel() + vector& sort_descending_parallel() { return sort_parallel(std::greater_equal()); } @@ -603,7 +603,7 @@ class vector // std::string name; // }; // ... - // const functional_vector persons_vector({ + // const fcpp::vector persons_vector({ // person(45, "Jake"), person(34, "Bob"), person(52, "Manfred"), person(8, "Alice") // }); // auto sorted_persons_vector = persons_vector.sorted([](const auto& person1, const auto& person2) { @@ -611,7 +611,7 @@ class vector // }); // // outcome: - // sorted_persons_vector -> functional_vector({ + // sorted_persons_vector -> fcpp::vector({ // person(8, "Alice"), person(34, "Bob"), person(45, "Jake"), person(52, "Manfred") // }); #ifdef CPP17_AVAILABLE @@ -632,25 +632,25 @@ class vector // Performs the `sorted` algorithm in parallel. // See also the sequential version for more documentation. template >> - functional_vector sorted_parallel(Sortable && comparison_predicate) const + vector sorted_parallel(Sortable && comparison_predicate) const { auto sorted_vector(backing_vector_); std::sort(std::execution::par, sorted_vector.begin(), sorted_vector.end(), std::forward(comparison_predicate)); - return functional_vector(sorted_vector); + return fcpp::vector(sorted_vector); } #endif // Sorts its elements copied and sorted in ascending order, when its elements support comparison by std::less_equal [<=] (non-mutating). // // example: - // const functional_vector numbers({3, 1, 9, -4}); + // const fcpp::vector numbers({3, 1, 9, -4}); // auto sorted_numbers = numbers.sorted_ascending(); // // outcome: - // sorted_numbers -> functional_vector({-4, 1, 3, 9}); + // sorted_numbers -> fcpp::vector({-4, 1, 3, 9}); [[nodiscard]] vector sorted_ascending() const { return sorted(std::less_equal()); @@ -659,7 +659,7 @@ class vector #ifdef PARALLEL_ALGORITHM_AVAILABLE // Performs the `sorted_ascending` algorithm in parallel. // See also the sequential version for more documentation. - [[nodiscard]] functional_vector sorted_ascending_parallel() const + [[nodiscard]] vector sorted_ascending_parallel() const { return sorted_parallel(std::less_equal()); } @@ -668,11 +668,11 @@ class vector // Sorts its elements copied and sorted in descending order, when its elements support comparison by std::greater_equal [>=] (non-mutating). // // example: - // const functional_vector numbers({3, 1, 9, -4}); + // const fcpp::vector numbers({3, 1, 9, -4}); // auto sorted_numbers = numbers.sorted_descending(); // // outcome: - // sorted_numbers -> functional_vector({9, 3, 1, -4}); + // sorted_numbers -> fcpp::vector({9, 3, 1, -4}); [[nodiscard]] vector sorted_descending() const { return sorted(std::greater_equal()); @@ -681,7 +681,7 @@ class vector #ifdef PARALLEL_ALGORITHM_AVAILABLE // Performs the `sorted_descending` algorithm in parallel. // See also the sequential version for more documentation. - [[nodiscard]] functional_vector sorted_descending_parallel() const + [[nodiscard]] vector sorted_descending_parallel() const { return sorted_parallel(std::greater_equal()); } @@ -706,7 +706,7 @@ class vector // Executes the given operation for each element of the vector in parallel. The operation must not // change the vector's contents during execution. template >> - const functional_vector& for_each_parallel(Callable && operation) const + const vector& for_each_parallel(Callable && operation) const { std::for_each(std::execution::par, backing_vector_.cbegin(), @@ -721,7 +721,7 @@ class vector // (see find_all_indices for multiple occurrences). // // example: - // const functional_vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); + // const fcpp::vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); // const auto index_of_one = numbers.find_first_index(1); // const auto index_of_nine = numbers.find_first_index(9); // @@ -746,7 +746,7 @@ class vector // (see find_all_indices for multiple occurrences). // // example: - // const functional_vector numbers({1, 4, 2, 5, -6, 3, 1, 7, 1}); + // const fcpp::vector numbers({1, 4, 2, 5, -6, 3, 1, 7, 1}); // const auto index_of_one = numbers.find_last_index(1); // const auto index_of_nine = numbers.find_last_index(9); // @@ -769,7 +769,7 @@ class vector // Returns all indices in which the given element is found in the vector. // // example: - // const functional_vector numbers({1, 4, 2, 5, 8, 3, 1, 9, 1}); + // const fcpp::vector numbers({1, 4, 2, 5, 8, 3, 1, 9, 1}); // const auto indices_of_one = numbers.find_all_indices(1); // const auto indices_of_ten = numbers.find_all_indices(10); // @@ -794,11 +794,11 @@ class vector // Removes the element at `index` (mutating) // // example: - // functional_vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); + // fcpp::vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); // numbers.remove_at(4); // // outcome: - // numbers -> functional_vector({1, 4, 2, 5, 3, 1, 7, 1}); + // numbers -> fcpp::vector({1, 4, 2, 5, 3, 1, 7, 1}); vector& remove_at(int index) { assert_smaller_size(index); @@ -809,11 +809,11 @@ class vector // Returns a copy of itself in which the element at `index` is removed (non-mutating) // // example: - // const functional_vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); + // const fcpp::vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); // auto shorter_vector = numbers.removing_at(4); // // outcome: - // shorter_vector -> functional_vector({1, 4, 2, 5, 3, 1, 7, 1}); + // shorter_vector -> fcpp::vector({1, 4, 2, 5, 3, 1, 7, 1}); [[nodiscard]] vector removing_at(int index) const { assert_smaller_size(index); @@ -825,11 +825,11 @@ class vector // Removes the last element, if present (mutating) // // example: - // functional_vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); + // fcpp::vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); // numbers.remove_back(); // // outcome: - // numbers -> functional_vector({1, 4, 2, 5, 8, 3, 1, 7}); + // numbers -> fcpp::vector({1, 4, 2, 5, 8, 3, 1, 7}); vector& remove_back() { backing_vector_.pop_back(); @@ -839,11 +839,11 @@ class vector // Returns a copy of itself in which the last element is removed (non-mutating) // // example: - // const functional_vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); + // const fcpp::vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); // auto shorter_vector = numbers.removing_back(); // // outcome: - // shorter_vector -> functional_vector({1, 4, 2, 5, 8, 3, 1, 7}); + // shorter_vector -> fcpp::vector({1, 4, 2, 5, 8, 3, 1, 7}); [[nodiscard]] vector removing_back() const { auto copy(backing_vector_); @@ -854,11 +854,11 @@ class vector // Removes the first element, if present (mutating) // // example: - // functional_vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); + // fcpp::vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); // numbers.remove_front(); // // outcome: - // numbers -> functional_vector({4, 2, 5, 8, 3, 1, 7, 1}); + // numbers -> fcpp::vector({4, 2, 5, 8, 3, 1, 7, 1}); vector& remove_front() { if (size() == 0) @@ -871,11 +871,11 @@ class vector // Returns a copy of itself in which the first element is removed (non-mutating) // // example: - // const functional_vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); + // const fcpp::vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); // auto shorter_numbers = numbers.removing_front(); // // outcome: - // shorter_numbers -> functional_vector({4, 2, 5, 8, 3, 1, 7, 1}); + // shorter_numbers -> fcpp::vector({4, 2, 5, 8, 3, 1, 7, 1}); [[nodiscard]] vector removing_front() const { if (size() == 0) @@ -888,11 +888,11 @@ class vector // Removes the elements whose index is contained in the given index range (mutating) // // example: - // functional_vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); + // fcpp::vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); // numbers.remove_range(index_range::start_count(2, 3)); // // outcome: - // numbers -> functional_vector({ 1, 4, 2, 7, 1 }) + // numbers -> fcpp::vector({ 1, 4, 2, 7, 1 }) vector& remove_range(index_range range) { if (!range.is_valid || size() < range.end + 1) @@ -907,11 +907,11 @@ class vector // Returns a copy by removing the elements whose index is contained in the given index range (non-mutating) // // example: - // const functional_vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); + // const fcpp::vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); // const auto shorter_vector = numbers.removing_range(index_range::start_count(2, 3)); // // outcome: - // shorter_vector -> functional_vector({ 1, 4, 3, 1, 7, 1 }) + // shorter_vector -> fcpp::vector({ 1, 4, 3, 1, 7, 1 }) [[nodiscard]] vector removing_range(index_range range) const { if (!range.is_valid || size() < range.end + 1) @@ -927,11 +927,11 @@ class vector // Inserts an element at the given index, therefore changing the vector's contents (mutating) // // example: - // functional_vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); + // fcpp::vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); // numbers.insert_at(3, 18); // // outcome: - // numbers -> functional_vector({1, 4, 2, 18, 5, 8, 3, 1, 7, 1}); + // numbers -> fcpp::vector({1, 4, 2, 18, 5, 8, 3, 1, 7, 1}); vector& insert_at(int index, const T& element) { assert_smaller_or_equal_size(index); @@ -942,11 +942,11 @@ class vector // Returns a copy by inserting an element at the given index (non-mutating) // // example: - // const functional_vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); + // const fcpp::vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); // auto augmented_numbers = numbers.inserting_at(3, 18); // // outcome: - // augmented_numbers -> functional_vector({1, 4, 2, 18, 5, 8, 3, 1, 7, 1}); + // augmented_numbers -> fcpp::vector({1, 4, 2, 18, 5, 8, 3, 1, 7, 1}); [[nodiscard]] vector inserting_at(int index, const T& element) const { assert_smaller_or_equal_size(index); @@ -958,12 +958,12 @@ class vector // Inserts a range of elements starting at the given index, therefore changing the vector's contents (mutating) // // example: - // functional_vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); - // const functional_vector vector_to_insert({9, -5, 6}); + // fcpp::vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); + // const fcpp::vector vector_to_insert({9, -5, 6}); // numbers.insert_at(3, vector_to_insert); // // outcome: - // numbers -> functional_vector({1, 4, 2, 9, -5, 6, 5, 8, 3, 1, 7, 1}); + // numbers -> fcpp::vector({1, 4, 2, 9, -5, 6, 5, 8, 3, 1, 7, 1}); vector& insert_at(int index, const vector& vector) { return insert_at_impl(index, vector.begin(), vector.end()); @@ -972,12 +972,12 @@ class vector // Returns a copy by inserting a range of elements starting at the given index (non-mutating) // // example: - // const functional_vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); - // const functional_vector vector_to_insert({9, -5, 6}); + // const fcpp::vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); + // const fcpp::vector vector_to_insert({9, -5, 6}); // auto augmented_numbers = numbers.inserting_at(3, vector_to_insert); // // outcome: - // augmented_numbers -> functional_vector({1, 4, 2, 9, -5, 6, 5, 8, 3, 1, 7, 1}); + // augmented_numbers -> fcpp::vector({1, 4, 2, 9, -5, 6, 5, 8, 3, 1, 7, 1}); [[nodiscard]] vector inserting_at(int index, const vector& vector) const { return inserting_at_impl(index, vector.begin(), vector.end()); @@ -986,12 +986,12 @@ class vector // Inserts a range of elements starting at the given index, therefore changing the vector's contents (mutating) // // example: - // functional_vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); + // fcpp::vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); // const std::vector vector_to_insert({9, -5, 6}); // numbers.insert_at(3, vector_to_insert); // // outcome: - // numbers -> functional_vector({1, 4, 2, 9, -5, 6, 5, 8, 3, 1, 7, 1}); + // numbers -> fcpp::vector({1, 4, 2, 9, -5, 6, 5, 8, 3, 1, 7, 1}); vector& insert_at(int index, const std::vector& vector) { return insert_at_impl(index, vector.cbegin(), vector.cend()); @@ -1000,12 +1000,12 @@ class vector // Returns a copy by inserting a range of elements starting at the given index (non-mutating) // // example: - // const functional_vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); + // const fcpp::vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); // const std::vector vector_to_insert({9, -5, 6}); // auto augmented_numbers = numbers.inserting_at(3, vector_to_insert); // // outcome: - // augmented_numbers -> functional_vector({1, 4, 2, 9, -5, 6, 5, 8, 3, 1, 7, 1}); + // augmented_numbers -> fcpp::vector({1, 4, 2, 9, -5, 6, 5, 8, 3, 1, 7, 1}); [[nodiscard]] vector inserting_at(int index, const std::vector& vector) const { return inserting_at_impl(index, vector.cbegin(), vector.cend()); @@ -1014,12 +1014,12 @@ class vector // Inserts a range of elements starting at the given index, therefore changing the vector's contents (mutating) // // example: - // functional_vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); + // fcpp::vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); // const std::initializer_list vector_to_insert({9, -5, 6}); // numbers.insert_at(3, vector_to_insert); // // outcome: - // numbers -> functional_vector({1, 4, 2, 9, -5, 6, 5, 8, 3, 1, 7, 1}); + // numbers -> fcpp::vector({1, 4, 2, 9, -5, 6, 5, 8, 3, 1, 7, 1}); vector& insert_at(int index, std::initializer_list list) { return insert_at(index, std::vector(std::move(list))); @@ -1028,12 +1028,12 @@ class vector // Returns a copy by inserting a range of elements starting at the given index (non-mutating) // // example: - // const functional_vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); + // const fcpp::vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); // const std::initializer_list vector_to_insert({9, -5, 6}); // auto augmented_numbers = numbers.inserting_at(3, vector_to_insert); // // outcome: - // augmented_numbers -> functional_vector({1, 4, 2, 9, -5, 6, 5, 8, 3, 1, 7, 1}); + // augmented_numbers -> fcpp::vector({1, 4, 2, 9, -5, 6, 5, 8, 3, 1, 7, 1}); [[nodiscard]] vector inserting_at(int index, std::initializer_list list) const { return inserting_at(index, std::vector(std::move(list))); @@ -1042,11 +1042,11 @@ class vector // Inserts a value at the end of the vector in place (mutating) // // example: - // functional_vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); + // fcpp::vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); // numbers.insert_back(18); // // outcome: - // numbers -> functional_vector({1, 4, 2, 5, 8, 3, 1, 7, 1, 18}); + // numbers -> fcpp::vector({1, 4, 2, 5, 8, 3, 1, 7, 1, 18}); vector& insert_back(T value) { backing_vector_.push_back(value); @@ -1056,11 +1056,11 @@ class vector // Inserts a value at the beginning of the vector in place (mutating) // // example: - // functional_vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); + // fcpp::vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); // numbers.insert_front(18); // // outcome: - // numbers -> functional_vector({18, 1, 4, 2, 5, 8, 3, 1, 7, 1}); + // numbers -> fcpp::vector({18, 1, 4, 2, 5, 8, 3, 1, 7, 1}); vector& insert_front(T value) { return insert_at(0, value); @@ -1069,11 +1069,11 @@ class vector // Makes a copy of the vector, inserts value at the end of the copy and returns the copy (non-mutating) // // example: - // const functional_vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); + // const fcpp::vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); // auto augmented_numbers = numbers.inserting_back(18); // // outcome: - // augmented_numbers -> functional_vector({1, 4, 2, 5, 8, 3, 1, 7, 1, 18}); + // augmented_numbers -> fcpp::vector({1, 4, 2, 5, 8, 3, 1, 7, 1, 18}); [[nodiscard]] vector inserting_back(T value) const { auto augmented_vector(backing_vector_); @@ -1084,11 +1084,11 @@ class vector // Makes a copy of the vector, inserts value at the beginning of the copy and returns the copy (non-mutating) // // example: - // const functional_vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); + // const fcpp::vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); // auto augmented_numbers = numbers.inserting_front(18); // // outcome: - // augmented_numbers -> functional_vector({18, 1, 4, 2, 5, 8, 3, 1, 7, 1}); + // augmented_numbers -> fcpp::vector({18, 1, 4, 2, 5, 8, 3, 1, 7, 1}); [[nodiscard]] vector inserting_front(T value) const { return inserting_at(0, value); @@ -1097,11 +1097,11 @@ class vector // Inserts a range of values at the end of the vector in place (mutating) // // example: - // functional_vector numbers({ 4, 5, 6 }); - // numbers.insert_back(functional_vector({1, 2, 3})); + // fcpp::vector numbers({ 4, 5, 6 }); + // numbers.insert_back(fcpp::vector({1, 2, 3})); // // outcome: - // numbers -> functional_vector numbers({ 4, 5, 6, 1, 2, 3 }); + // numbers -> fcpp::vector numbers({ 4, 5, 6, 1, 2, 3 }); vector& insert_back(const vector& vector) { return insert_back_range_impl(vector.begin(), vector.end()); @@ -1110,11 +1110,11 @@ class vector // Inserts a range of values at the beginning of the vector in place (mutating) // // example: - // functional_vector numbers({ 4, 5, 6 }); - // numbers.insert_front(functional_vector({1, 2, 3})); + // fcpp::vector numbers({ 4, 5, 6 }); + // numbers.insert_front(fcpp::vector({1, 2, 3})); // // outcome: - // numbers -> functional_vector numbers({ 1, 2, 3, 4, 5, 6 }); + // numbers -> fcpp::vector numbers({ 1, 2, 3, 4, 5, 6 }); vector& insert_front(const vector& vector) { return insert_front_range_impl(vector.begin(), vector.end()); @@ -1123,11 +1123,11 @@ class vector // Makes a copy of the vector, inserts a range of values at the end of the copy, and returns the copy (non-mutating) // // example: - // const functional_vector numbers({ 4, 5, 6 }); - // auto augmented_numbers = numbers.inserting_back(functional_vector({1, 2, 3})); + // const fcpp::vector numbers({ 4, 5, 6 }); + // auto augmented_numbers = numbers.inserting_back(fcpp::vector({1, 2, 3})); // // outcome: - // augmented_numbers -> functional_vector numbers({ 4, 5, 6, 1, 2, 3 }); + // augmented_numbers -> fcpp::vector numbers({ 4, 5, 6, 1, 2, 3 }); [[nodiscard]] vector inserting_back(const vector& vector) const { return inserting_back_range_impl(vector.begin(), vector.end()); @@ -1136,11 +1136,11 @@ class vector // Makes a copy of the vector, inserts a range of values at the beginning of the copy, and returns the copy (non-mutating) // // example: - // const functional_vector numbers({ 4, 5, 6 }); - // auto augmented_numbers = numbers.inserting_front(functional_vector({1, 2, 3})); + // const fcpp::vector numbers({ 4, 5, 6 }); + // auto augmented_numbers = numbers.inserting_front(fcpp::vector({1, 2, 3})); // // outcome: - // augmented_numbers -> functional_vector numbers({ 1, 2, 3, 4, 5, 6 }); + // augmented_numbers -> fcpp::vector numbers({ 1, 2, 3, 4, 5, 6 }); [[nodiscard]] vector inserting_front(const vector& vector) const { return inserting_front_range_impl(vector.begin(), vector.end()); @@ -1149,11 +1149,11 @@ class vector // Inserts a range of values at the end of the vector in place (mutating) // // example: - // functional_vector numbers({ 4, 5, 6 }); + // fcpp::vector numbers({ 4, 5, 6 }); // numbers.insert_back(std::vector({1, 2, 3})); // // outcome: - // numbers -> functional_vector numbers({ 4, 5, 6, 1, 2, 3 }); + // numbers -> fcpp::vector numbers({ 4, 5, 6, 1, 2, 3 }); vector& insert_back(const std::vector& vector) { return insert_back_range_impl(vector.cbegin(), vector.cend()); @@ -1162,11 +1162,11 @@ class vector // Inserts a range of values at the beginning of the vector in place (mutating) // // example: - // functional_vector numbers({ 4, 5, 6 }); + // fcpp::vector numbers({ 4, 5, 6 }); // numbers.insert_front(std::vector({1, 2, 3})); // // outcome: - // numbers -> functional_vector numbers({ 1, 2, 3, 4, 5, 6 }); + // numbers -> fcpp::vector numbers({ 1, 2, 3, 4, 5, 6 }); vector& insert_front(const std::vector& vector) { return insert_front_range_impl(vector.cbegin(), vector.cend()); @@ -1175,11 +1175,11 @@ class vector // Makes a copy of the vector, inserts a range of values at the end of the copy, and returns the copy (non-mutating) // // example: - // const functional_vector numbers({ 4, 5, 6 }); + // const fcpp::vector numbers({ 4, 5, 6 }); // auto augmented_numbers = numbers.inserting_back(std::vector({1, 2, 3})); // // outcome: - // augmented_numbers -> functional_vector numbers({ 4, 5, 6, 1, 2, 3 }); + // augmented_numbers -> fcpp::vector numbers({ 4, 5, 6, 1, 2, 3 }); [[nodiscard]] vector inserting_back(const std::vector& vector) const { return inserting_back_range_impl(vector.cbegin(), vector.cend()); @@ -1188,11 +1188,11 @@ class vector // Makes a copy of the vector, inserts a range of values at the beginning of the copy, and returns the copy (non-mutating) // // example: - // const functional_vector numbers({ 4, 5, 6 }); + // const fcpp::vector numbers({ 4, 5, 6 }); // auto augmented_numbers = numbers.inserting_front(std::vector({1, 2, 3})); // // outcome: - // augmented_numbers -> functional_vector numbers({ 1, 2, 3, 4, 5, 6 }); + // augmented_numbers -> fcpp::vector numbers({ 1, 2, 3, 4, 5, 6 }); [[nodiscard]] vector inserting_front(const std::vector& vector) const { return inserting_front_range_impl(vector.cbegin(), vector.cend()); @@ -1201,11 +1201,11 @@ class vector // Inserts a range of values at the end of the vector in place (mutating) // // example: - // functional_vector numbers({ 4, 5, 6 }); + // fcpp::vector numbers({ 4, 5, 6 }); // numbers.insert_back(std::initializer_list({1, 2, 3})); // // outcome: - // numbers -> functional_vector numbers({ 4, 5, 6, 1, 2, 3 }); + // numbers -> fcpp::vector numbers({ 4, 5, 6, 1, 2, 3 }); vector& insert_back(const std::initializer_list& list) { return insert_back(std::vector(list)); @@ -1214,11 +1214,11 @@ class vector // Inserts a range of values at the beginning of the vector in place (mutating) // // example: - // functional_vector numbers({ 4, 5, 6 }); + // fcpp::vector numbers({ 4, 5, 6 }); // numbers.insert_front(std::initializer_list({1, 2, 3})); // // outcome: - // numbers -> functional_vector numbers({ 1, 2, 3, 4, 5, 6 }); + // numbers -> fcpp::vector numbers({ 1, 2, 3, 4, 5, 6 }); vector& insert_front(const std::initializer_list& list) { return insert_front(std::vector(list)); @@ -1227,11 +1227,11 @@ class vector // Makes a copy of the vector, inserts a range of values at the end of the copy, and returns the copy (non-mutating) // // example: - // const functional_vector numbers({ 4, 5, 6 }); + // const fcpp::vector numbers({ 4, 5, 6 }); // auto augmented_numbers = numbers.inserting_back(std::initializer_list({1, 2, 3})); // // outcome: - // augmented_numbers -> functional_vector numbers({ 4, 5, 6, 1, 2, 3 }); + // augmented_numbers -> fcpp::vector numbers({ 4, 5, 6, 1, 2, 3 }); [[nodiscard]] vector inserting_back(const std::initializer_list& list) const { return inserting_back(std::vector(list)); @@ -1240,11 +1240,11 @@ class vector // Makes a copy of the vector, inserts a range of values at the beginning of the copy, and returns the copy (non-mutating) // // example: - // const functional_vector numbers({ 4, 5, 6 }); + // const fcpp::vector numbers({ 4, 5, 6 }); // auto augmented_numbers = numbers.inserting_front(std::initializer_list({1, 2, 3})); // // outcome: - // augmented_numbers -> functional_vector numbers({ 1, 2, 3, 4, 5, 6 }); + // augmented_numbers -> fcpp::vector numbers({ 1, 2, 3, 4, 5, 6 }); [[nodiscard]] vector inserting_front(const std::initializer_list& list) const { return inserting_front(std::vector(list)); @@ -1253,11 +1253,11 @@ class vector // Replaces the existing contents starting at `index` with the contents of the given vector (mutating) // // example: - // functional_vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); - // numbers.replace_range_at(4, functional_vector({9, -10, 8})); + // fcpp::vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); + // numbers.replace_range_at(4, fcpp::vector({9, -10, 8})); // // outcome: - // numbers -> functional_vector({ 1, 4, 2, 5, 9, -10, 8, 7, 1 }) + // numbers -> fcpp::vector({ 1, 4, 2, 5, 9, -10, 8, 7, 1 }) vector& replace_range_at(int index, const vector& vector) { return replace_range_at_imp(index, vector.begin(), vector.end()); @@ -1266,11 +1266,11 @@ class vector // Replaces the existing contents starting at `index` with the contents of the given vector (mutating) // // example: - // functional_vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); + // fcpp::vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); // numbers.replace_range_at(4, std::vector({9, -10, 8})); // // outcome: - // numbers -> functional_vector({ 1, 4, 2, 5, 9, -10, 8, 7, 1 }) + // numbers -> fcpp::vector({ 1, 4, 2, 5, 9, -10, 8, 7, 1 }) vector& replace_range_at(int index, const std::vector& vector) { return replace_range_at_imp(index, vector.cbegin(), vector.cend()); @@ -1279,11 +1279,11 @@ class vector // Replaces the existing contents starting at `index` with the contents of the given vector (mutating) // // example: - // functional_vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); + // fcpp::vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); // numbers.replace_range_at(4, std::initializer_list({9, -10, 8})); // // outcome: - // numbers -> functional_vector({ 1, 4, 2, 5, 9, -10, 8, 7, 1 }) + // numbers -> fcpp::vector({ 1, 4, 2, 5, 9, -10, 8, 7, 1 }) vector& replace_range_at(int index, const std::initializer_list& list) { return replace_range_at(index, std::vector(list)); @@ -1292,11 +1292,11 @@ class vector // Returns a copy whose elements starting at `index` are replaced with the contents of the given vector (non-mutating) // // example: - // const functional_vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); - // auto replaced_numbers = numbers.replacing_range_at(4, functional_vector({9, -10, 8})); + // const fcpp::vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); + // auto replaced_numbers = numbers.replacing_range_at(4, fcpp::vector({9, -10, 8})); // // outcome: - // replaced_numbers -> functional_vector({ 1, 4, 2, 5, 9, -10, 8, 7, 1 }) + // replaced_numbers -> fcpp::vector({ 1, 4, 2, 5, 9, -10, 8, 7, 1 }) [[nodiscard]] vector replacing_range_at(int index, const vector& vector) const { return replacing_range_at_imp(index, vector.begin(), vector.end()); @@ -1305,11 +1305,11 @@ class vector // Returns a copy whose elements starting at `index` are replaced with the contents of the given vector (non-mutating) // // example: - // const functional_vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); + // const fcpp::vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); // auto replaced_numbers = numbers.replacing_range_at(4, std::vector({9, -10, 8})); // // outcome: - // replaced_numbers -> functional_vector({ 1, 4, 2, 5, 9, -10, 8, 7, 1 }) + // replaced_numbers -> fcpp::vector({ 1, 4, 2, 5, 9, -10, 8, 7, 1 }) [[nodiscard]] vector replacing_range_at(int index, const std::vector& vector) const { return replacing_range_at_imp(index, vector.cbegin(), vector.cend()); @@ -1318,11 +1318,11 @@ class vector // Returns a copy whose elements starting at `index` are replaced with the contents of the given vector (non-mutating) // // example: - // const functional_vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); + // const fcpp::vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); // auto replaced_numbers = numbers.replacing_range_at(4, std::initializer_list({9, -10, 8})); // // outcome: - // replaced_numbers -> functional_vector({ 1, 4, 2, 5, 9, -10, 8, 7, 1 }) + // replaced_numbers -> fcpp::vector({ 1, 4, 2, 5, 9, -10, 8, 7, 1 }) [[nodiscard]] vector replacing_range_at(int index, const std::initializer_list& list) const { return replacing_range_at(index, std::vector(list)); @@ -1331,11 +1331,11 @@ class vector // Replaces all existing elements with a constant element (mutating) // // example: - // functional_vector numbers({1, 3, -6, 4, -9}); + // fcpp::vector numbers({1, 3, -6, 4, -9}); // numbers.fill(7); // // outcome: - // numbers -> functional_vector({ 7, 7, 7, 7, 7 }) + // numbers -> fcpp::vector({ 7, 7, 7, 7, 7 }) vector& fill(const T& element) { std::fill(backing_vector_.begin(), @@ -1384,20 +1384,20 @@ class vector // example: // // numbers.capacity() = 9 // // numbers.size() = 9 - // functional_vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); + // fcpp::vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); // // numbers.capacity() = 9 // // numbers.size() = 5 - // // numbers -> functional_vector({1, 4, 2, 5, 8}); + // // numbers -> fcpp::vector({1, 4, 2, 5, 8}); // numbers.resize(5); // // // empty_numbers.capacity() = 0 // // empty_numbers.size() = 0 - // functional_vector empty_numbers; + // fcpp::vector empty_numbers; // // // empty_numbers.capacity() = 5 // // empty_numbers.size() = 5 - // // empty_numbers -> functional_vector({0, 0, 0, 0, 0}); + // // empty_numbers -> fcpp::vector({0, 0, 0, 0, 0}); // empty_numbers.resize(5); vector& resize(size_t count) { @@ -1432,7 +1432,7 @@ class vector // Returns a set, whose elements are the elements of the vector, removing any potential duplicates // // example: - // const functional_vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); + // const fcpp::vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); // const auto& unique_numbers = numbers.distinct(); // // outcome: @@ -1549,7 +1549,7 @@ class vector #ifdef CPP17_AVAILABLE template::value>> [[nodiscard]] auto zip_impl( const Iterator& vec_begin, const Iterator& vec_end) const -> - functional_vector>> + vector>> { using U = deref_type; #else From e645dc479d5a632bf34ea9e03fc32fd849748d18 Mon Sep 17 00:00:00 2001 From: jkaliak Date: Thu, 14 Jul 2022 21:40:36 +0200 Subject: [PATCH 40/44] last functional_vector references for C++17 in Windows/Linux --- tests/vector_test.cc | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/vector_test.cc b/tests/vector_test.cc index 0842784..ebd75ca 100644 --- a/tests/vector_test.cc +++ b/tests/vector_test.cc @@ -193,7 +193,7 @@ TEST(VectorTest, Map) #ifdef PARALLEL_ALGORITHM_AVAILABLE TEST(VectorTest, MapParallel) { - const functional_vector vector_under_test({1, 3, 4}); + const vector vector_under_test({1, 3, 4}); const auto mapped_vector = vector_under_test.map_parallel([](const int& age) { return child(age); }); @@ -221,7 +221,7 @@ TEST(VectorTest, Filter) #ifdef PARALLEL_ALGORITHM_AVAILABLE TEST(VectorTest, FilterParallel) { - functional_vector vector_under_test({child(1), child(3), child(4)}); + vector vector_under_test({child(1), child(3), child(4)}); vector_under_test.filter_parallel([](const child& child) { return child.age < 2; }); @@ -248,7 +248,7 @@ TEST(VectorTest, Filtered) #ifdef PARALLEL_ALGORITHM_AVAILABLE TEST(VectorTest, FilteredParallel) { - const functional_vector vector_under_test({child(1), child(3), child(4)}); + const vector vector_under_test({child(1), child(3), child(4)}); const auto filtered_vector = vector_under_test.filtered_parallel([](const child& child) { return child.age < 2; }); @@ -458,7 +458,7 @@ TEST(VectorTest, SortedDescending) #ifdef PARALLEL_ALGORITHM_AVAILABLE TEST(VectorTest, SortParallel) { - functional_vector vector_under_test({ + vector vector_under_test({ person(45, "Jake"), person(34, "Bob"), person(52, "Manfred"), person(8, "Alice") }); vector_under_test.sort_parallel([](const person& person1, const person& person2){ @@ -481,7 +481,7 @@ TEST(VectorTest, SortParallel) TEST(VectorTest, SortedParallel) { - const functional_vector vector_under_test({ + const vector vector_under_test({ person(45, "Jake"), person(34, "Bob"), person(52, "Manfred"), person(8, "Alice") }); const auto sorted_vector = vector_under_test.sorted_parallel([](const person& person1, const person& person2){ @@ -511,7 +511,7 @@ TEST(VectorTest, SortedParallel) TEST(VectorTest, SortAscendingParallel) { - functional_vector vector_under_test({3, 1, 9, -4}); + vector vector_under_test({3, 1, 9, -4}); vector_under_test.sort_ascending_parallel(); EXPECT_EQ(4, vector_under_test.size()); EXPECT_EQ(-4, vector_under_test[0]); @@ -522,7 +522,7 @@ TEST(VectorTest, SortAscendingParallel) TEST(VectorTest, SortedAscendingParallel) { - const functional_vector vector_under_test({3, 1, 9, -4}); + const vector vector_under_test({3, 1, 9, -4}); const auto sorted_vector = vector_under_test.sorted_ascending_parallel(); EXPECT_EQ(4, vector_under_test.size()); EXPECT_EQ(3, vector_under_test[0]); @@ -539,7 +539,7 @@ TEST(VectorTest, SortedAscendingParallel) TEST(VectorTest, SortDescendingParallel) { - functional_vector vector_under_test({3, 1, 9, -4}); + vector vector_under_test({3, 1, 9, -4}); vector_under_test.sort_descending_parallel(); EXPECT_EQ(4, vector_under_test.size()); EXPECT_EQ(9, vector_under_test[0]); @@ -550,7 +550,7 @@ TEST(VectorTest, SortDescendingParallel) TEST(VectorTest, SortedDescendingParallel) { - const functional_vector vector_under_test({3, 1, 9, -4}); + const vector vector_under_test({3, 1, 9, -4}); const auto sorted_vector = vector_under_test.sorted_descending_parallel(); EXPECT_EQ(4, vector_under_test.size()); EXPECT_EQ(3, vector_under_test[0]); @@ -1250,13 +1250,13 @@ TEST(VectorTest, AllOfTrue) #ifdef PARALLEL_ALGORITHM_AVAILABLE TEST(VectorTest, AllOfParallelFalse) { - functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_FALSE(vector_under_test.all_of_parallel([](const int& number) { return number > 5; })); } TEST(VectorTest, AllOfParallelTrue) { - functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); vector_under_test.all_of([](const int& number) { return number < 10; }); @@ -1279,13 +1279,13 @@ TEST(VectorTest, AnyOfTrue) #ifdef PARALLEL_ALGORITHM_AVAILABLE TEST(VectorTest, AnyOfParallelFalse) { - functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_FALSE(vector_under_test.any_of_parallel([](const int& number) { return number > 20; })); } TEST(VectorTest, AnyOfParallelTrue) { - functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_TRUE(vector_under_test.any_of_parallel([](const int& number) { return number >= 7; })); } #endif @@ -1305,19 +1305,19 @@ TEST(VectorTest, NoneOfTrue) #ifdef PARALLEL_ALGORITHM_AVAILABLE TEST(VectorTest, NoneOfParallelFalse) { - functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_FALSE(vector_under_test.none_of_parallel([](const int& number) { return number > 7; })); } TEST(VectorTest, NoneOfParallelTrue) { - functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_TRUE(vector_under_test.none_of_parallel([](const int& number) { return number < -2; })); } TEST(VectorTest, ForEachParallel) { - functional_vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); + vector vector_under_test({1, 4, 2, 5, 8, 3, 1, 7, 1}); EXPECT_EQ(9, vector_under_test.size()); std::atomic counter(0); vector_under_test.for_each_parallel([&](const int& element) { ++counter; }); From 4540a3a250b367ce4e2c96992d7811637b69423a Mon Sep 17 00:00:00 2001 From: jkaliak Date: Thu, 14 Jul 2022 22:35:14 +0200 Subject: [PATCH 41/44] finished documentation --- README.md | 199 +++++++++++++++++++++++++++++++++++++++++++---- include/set.h | 2 +- include/vector.h | 2 +- 3 files changed, 187 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 3b6adc4..022443a 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,17 @@ cmake -S . -B build ``` Then open the generated ```functional_cpp.sln``` in the ```build``` folder. -## Usage (fcpp::vector) +## Functional vector usage (fcpp::vector) +### extract unique (distinct) elements +```c++ +#include "vector.h" // instead of + +const fcpp::vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); + +// contains only 1, 2, 3, 4, 5, 7, 8 +const auto& unique_numbers = numbers.distinct(); +``` + ### zip, map, filter, sort ```c++ #include "vector.h" // instead of @@ -87,17 +97,17 @@ const auto employees_below_40 = ages .zip(names) // apply the functional map algorithm (transform from one type to another) - .map([](const auto& pair) { + .map([](const std::pair& pair) { return person(pair.first, pair.second); }) // filter the elements using a local function (lambda) - .filter([](const auto& person) { - return person.age < 40; + .filter([](const person& p) { + return p.age < 40; }) // sort according to custom predicate - .sort([](const auto& person1, const auto& person2) { + .sort([](const person& person1, const person& person2) { return person1.age < person2.age; }); @@ -107,8 +117,8 @@ const auto employees_below_40 = ages Jake is 32 years old. Kate is 37 years old. */ -employees_below_40.for_each([](const auto& person) { - std::cout << person.name << " is " << person.age << " years old." << std::endl; +employees_below_40.for_each([](const person& p) { + std::cout << p.name << " is " << p.age << " years old." << std::endl; }); ``` ### index search @@ -171,7 +181,7 @@ numbers.insert_front(fcpp::vector({4, -6, 7})); numbers.insert_back(std::initializer_list({7, 3})); ``` -### size/capacity, reserve/resize +### size, capacity, reserve, resize ```c++ #include "vector.h" // instead of @@ -205,32 +215,32 @@ empty_numbers.reserve(5); fcpp::vector numbers({1, 4, 2, 5, 8, 3, 1, 7, 1}); // returns true -numbers.all_of([](const auto &number) { +numbers.all_of([](const int& number) { return number < 10; }); // returns false -numbers.all_of([](const auto &number) { +numbers.all_of([](const int& number) { return number > 2; }); // returns true -numbers.any_of([](const auto &number) { +numbers.any_of([](const int& number) { return number < 5; }); // returns false -numbers.any_of([](const auto &number) { +numbers.any_of([](const int& number) { return number > 9; }); // returns true -numbers.none_of([](const auto &number) { +numbers.none_of([](const int& number) { return number < -2; }); // returns false -numbers.none_of([](const auto &number) { +numbers.none_of([](const int& number) { return number > 7; }); ``` @@ -248,3 +258,164 @@ all_of_parallel any_of_parallel none_of_parallel ``` + +## Functional set usage (fcpp::set) +### difference, union, intersection (works with fcpp::set and std::set) +```c++ +#include "set.h" // instead of + +struct person +{ + person(int age, std::string name) + : age(age), name(std::move(name)) + { + } + + int age; + std::string name; + + // ... + // ... + + std::size_t hash() const { + // a clever implementation of hash + // ... + } + + bool operator< (const person& other) const { + return hash() < other.hash(); + } +}; + +struct person_comparator { + bool operator() (const person& a, const person& b) const { + return a < b; + } +}; + +// ... + +const fcpp::set colleagues({ + person(51, "George"), + person(15, "Jake"), + person(18, "Jannet"), + person(41, "Jackie"), + person(25, "Kate") +}); + +const fcpp::set friends({ + person(51, "George"), + person(41, "Jackie"), + person(42, "Crystal"), +}); + +// contains person(15, "Jake"), person(18, "Jannet") and person(25, "Kate") +const auto colleagues_but_not_friends = colleagues.difference_with(friends); + +// contains person(51, "George"), person(41, "Jackie") +const auto good_colleagues = colleagues.intersection_with(friends); + +const fcpp::set family({ + person(51, "Paul"), + person(81, "Barbara"), +}); + +// contains person(51, "George"), person(41, "Jackie"), person(42, "Crystal"), person(51, "Paul"), person(81, "Barbara") +const auto friends_and_family = friends.union_with(family); +``` + +### zip, map, filter +```c++ +#include "set.h" // instead of + +// the employees' ages +const fcpp::set ages({ 25, 45, 30, 63 }); + +// the employees' names +const fcpp::set names({ "Jake", "Bob", "Michael", "Philipp" }); + +const auto employees_below_40 = ages + // zip two vectors for simultaneous processing + .zip(names) + + // apply the functional map algorithm (transform from one type to another) + .map([](const std::pair& pair) { + return person(pair.first, pair.second); + }) + + // filter the elements using a local function (lambda) + .filter([](const person& p) { + return p.age < 40; + }); + +/* + prints the following: + Jake is 30 years old. + Bob is 25 years old. + */ +employees_below_40.for_each([](const person& p) { + std::cout << p.name << " is " << p.age << " years old." << std::endl; +}); +``` + +### all_of, any_of, none_of +```c++ +#include "set.h" // instead of + +fcpp::set numbers({1, 4, 2, 5, 8, 3, 7}); + +// returns true +numbers.all_of([](const int& number) { + return number < 10; +}); + +// returns false +numbers.all_of([](const int& number) { + return number > 2; +}); + +// returns true +numbers.any_of([](const int& number) { + return number < 5; +}); + +// returns false +numbers.any_of([](const int& number) { + return number > 9; +}); + +// returns true +numbers.none_of([](const int& number) { + return number < -2; +}); + +// returns false +numbers.none_of([](const int& number) { + return number > 7; +}); +``` + +### remove, insert, contains, size, clear +```c++ +#include "set.h" // instead of + +fcpp::set numbers({1, 2, 3, 4, 5, 7, 8}); + +// numbers -> fcpp::set numbers({1, 2, 3, 5, 7, 8}); +numbers.remove(4); + +// numbers -> fcpp::set numbers({1, 2, 3, 5, 7, 8, 10}); +numbers.insert(10); + +// returns true +numbers.contains(10); + +// returns false +numbers.contains(25); + +// returns 7 +numbers.size(); + +// removes all keys +numbers.clear(); +``` diff --git a/include/set.h b/include/set.h index 1f3df2e..ed7a054 100644 --- a/include/set.h +++ b/include/set.h @@ -184,7 +184,7 @@ class set // output of applying the transform function on every element of this instance. // // example: - // const functional_vector input_set({ 1, 3, -5 }); + // const fcpp::vector input_set({ 1, 3, -5 }); // const auto output_set = input_set.map([](const int& element) { // return std::to_string(element); // }); diff --git a/include/vector.h b/include/vector.h index 2cbc0f1..7f39572 100644 --- a/include/vector.h +++ b/include/vector.h @@ -1436,7 +1436,7 @@ class vector // const auto& unique_numbers = numbers.distinct(); // // outcome: - // unique_numbers -> functional_set({1, 2, 3, 4, 5, 7, 8}) + // unique_numbers -> fcpp::set({1, 2, 3, 4, 5, 7, 8}) template > set distinct() const { return set(*this); From cfc61a08033f5ab43b6b2a40516c2869021333c2 Mon Sep 17 00:00:00 2001 From: jkaliak Date: Thu, 14 Jul 2022 22:40:15 +0200 Subject: [PATCH 42/44] documentation --- README.md | 33 ++++++++++----------------------- 1 file changed, 10 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 022443a..02446d4 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,15 @@ struct person { {} int age; std::string name; + + std::size_t hash() const { + // a clever implementation of hash + // ... + } + + bool operator< (const person& other) const { + return hash() < other.hash(); + } }; // ... @@ -264,29 +273,7 @@ none_of_parallel ```c++ #include "set.h" // instead of -struct person -{ - person(int age, std::string name) - : age(age), name(std::move(name)) - { - } - - int age; - std::string name; - - // ... - // ... - - std::size_t hash() const { - // a clever implementation of hash - // ... - } - - bool operator< (const person& other) const { - return hash() < other.hash(); - } -}; - +// struct person as defined previously struct person_comparator { bool operator() (const person& a, const person& b) const { return a < b; From 087b6ef79ecdfd7a71d49d065ad645a14fba0385 Mon Sep 17 00:00:00 2001 From: jkaliak Date: Thu, 14 Jul 2022 22:47:12 +0200 Subject: [PATCH 43/44] more documentation --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 02446d4..32c1a5f 100644 --- a/README.md +++ b/README.md @@ -282,6 +282,7 @@ struct person_comparator { // ... +// a set containing all colleagues const fcpp::set colleagues({ person(51, "George"), person(15, "Jake"), @@ -290,23 +291,29 @@ const fcpp::set colleagues({ person(25, "Kate") }); +// a set containing all friends const fcpp::set friends({ person(51, "George"), person(41, "Jackie"), person(42, "Crystal"), }); +// find which colleagues are not friends // contains person(15, "Jake"), person(18, "Jannet") and person(25, "Kate") const auto colleagues_but_not_friends = colleagues.difference_with(friends); +// find which friends are colleagues +// same as colleagues.intersect_with(friends) // contains person(51, "George"), person(41, "Jackie") -const auto good_colleagues = colleagues.intersection_with(friends); +const auto good_colleagues = friends.intersection_with(colleagues); +// a set of close family members const fcpp::set family({ person(51, "Paul"), person(81, "Barbara"), }); +// all of our friends and family for the next party invitation // contains person(51, "George"), person(41, "Jackie"), person(42, "Crystal"), person(51, "Paul"), person(81, "Barbara") const auto friends_and_family = friends.union_with(family); ``` From 70bbb64d62e6d9c7f68db77094e4307c7998bc7d Mon Sep 17 00:00:00 2001 From: jkaliak Date: Thu, 14 Jul 2022 22:49:33 +0200 Subject: [PATCH 44/44] typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 32c1a5f..1e4aa24 100644 --- a/README.md +++ b/README.md @@ -329,7 +329,7 @@ const fcpp::set ages({ 25, 45, 30, 63 }); const fcpp::set names({ "Jake", "Bob", "Michael", "Philipp" }); const auto employees_below_40 = ages - // zip two vectors for simultaneous processing + // zip two sets for simultaneous processing .zip(names) // apply the functional map algorithm (transform from one type to another)