diff --git a/SimoxUtility/CMakeLists.txt b/SimoxUtility/CMakeLists.txt index ee77716ff8b9d9fd839a02334fa223be21939ecc..0f8f6b23084737ee775486d6f084e26970f1c9bf 100644 --- a/SimoxUtility/CMakeLists.txt +++ b/SimoxUtility/CMakeLists.txt @@ -54,6 +54,8 @@ SET(INCLUDES meta/eigen/enable_if_compile_time_size.h + algorithm/for_each_if.h + shapes/OrientedBoxBase.h shapes/OrientedBox.h shapes/XYConstrainedOrientedBox.h diff --git a/SimoxUtility/algorithm.h b/SimoxUtility/algorithm.h new file mode 100644 index 0000000000000000000000000000000000000000..42ef8c2098ca5e1d188c5b5568812cf3033cccbb --- /dev/null +++ b/SimoxUtility/algorithm.h @@ -0,0 +1,5 @@ +#pragma once + +// This file is generated! + +#include "algorithm/for_each_if.h" diff --git a/SimoxUtility/algorithm/for_each_if.h b/SimoxUtility/algorithm/for_each_if.h new file mode 100644 index 0000000000000000000000000000000000000000..52c585a3b269a74dbd611646df88bcedb47a316a --- /dev/null +++ b/SimoxUtility/algorithm/for_each_if.h @@ -0,0 +1,28 @@ +#pragma once + +namespace simox +{ + template<class InputIt, class DecisionFunc, class IfTrueFunc, class IfFalseFunc> + std::size_t for_each_if(InputIt first, InputIt last, DecisionFunc d, IfTrueFunc t, IfFalseFunc f) + { + std::size_t numTrue = 0; + for (; first != last; ++first) + { + if (d(*first)) + { + ++numTrue; + t(*first); + } + else + { + f(*first); + } + } + return numTrue; + } + template<class Container, class DecisionFunc, class IfTrueFunc, class IfFalseFunc> + std::size_t for_each_if(const Container& cont, DecisionFunc d, IfTrueFunc t, IfFalseFunc f) + { + return for_each_if(cont.begin(), cont.end(), std::move(d), std::move(t), std::move(f)); + } +} diff --git a/SimoxUtility/tests/CMakeLists.txt b/SimoxUtility/tests/CMakeLists.txt index 1aaf8b9763dd280c76c88802da36265d9059b865..ebecefb541c34690eabf32c182bf032ca3f42ddd 100644 --- a/SimoxUtility/tests/CMakeLists.txt +++ b/SimoxUtility/tests/CMakeLists.txt @@ -15,3 +15,4 @@ ADD_SU_TEST( OrientedBoxTest ) ADD_SU_TEST( XYConstrainedOrientedBoxTest ) ADD_SU_TEST( DeltaAngleTest ) ADD_SU_TEST( ConverterTest ) +ADD_SU_TEST( ForEachIf ) diff --git a/SimoxUtility/tests/ForEachIf.cpp b/SimoxUtility/tests/ForEachIf.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a174519fca5b1b31c45b727cea282c0e09a815f0 --- /dev/null +++ b/SimoxUtility/tests/ForEachIf.cpp @@ -0,0 +1,55 @@ +/** +* @package SimoxUtility +* @author Raphael Grimm +* @copyright 2019 Raphael Grimm +*/ + +#define BOOST_TEST_MODULE SimoxUtility_for_each_if + +#include <random> +#include <iostream> + +#include <boost/test/included/unit_test.hpp> + +#include <SimoxUtility/algorithm/for_each_if.h> + +BOOST_AUTO_TEST_CASE(test_for_each_if) +{ + std::mt19937 gen{std::random_device{}()}; + std::vector<std::size_t> num; + std::size_t even = 0; + for(int i = 0; i < 1000; ++i) + { + num.emplace_back(gen()); + if(0 == (num.back() % 2)) + { + ++even; + } + } + { + std::size_t cntEven = 0; + std::size_t cntOdd = 0; + + simox::for_each_if( + num, + [](auto n){return n%2;}, + [&cntOdd](auto){++cntOdd;}, + [&cntEven](auto){++cntEven;} + ); + BOOST_CHECK_EQUAL(cntEven, even); + BOOST_CHECK_EQUAL(cntEven + cntOdd, num.size()); + } + { + std::size_t cntEven = 0; + std::size_t cntOdd = 0; + + simox::for_each_if( + num.begin(), num.end(), + [](auto n){return n%2;}, + [&cntOdd](auto){++cntOdd;}, + [&cntEven](auto){++cntEven;} + ); + BOOST_CHECK_EQUAL(cntEven, even); + BOOST_CHECK_EQUAL(cntEven + cntOdd, num.size()); + } +}