mirror of
https://github.com/NGSolve/netgen.git
synced 2024-12-24 21:10:33 +05:00
add range adaptors (filter, transform)
This commit is contained in:
parent
283db5c637
commit
1666155d25
@ -65,7 +65,7 @@ target_link_libraries(ngcore PUBLIC netgen_mpi PRIVATE netgen_python ${CMAKE_THR
|
|||||||
install(FILES ngcore.hpp archive.hpp type_traits.hpp version.hpp ngcore_api.hpp logging.hpp
|
install(FILES ngcore.hpp archive.hpp type_traits.hpp version.hpp ngcore_api.hpp logging.hpp
|
||||||
exception.hpp symboltable.hpp paje_trace.hpp utils.hpp profiler.hpp mpi_wrapper.hpp
|
exception.hpp symboltable.hpp paje_trace.hpp utils.hpp profiler.hpp mpi_wrapper.hpp
|
||||||
array.hpp taskmanager.hpp concurrentqueue.h localheap.hpp python_ngcore.hpp flags.hpp
|
array.hpp taskmanager.hpp concurrentqueue.h localheap.hpp python_ngcore.hpp flags.hpp
|
||||||
xbool.hpp signal.hpp bitarray.hpp table.hpp hashtable.hpp
|
xbool.hpp signal.hpp bitarray.hpp table.hpp hashtable.hpp ranges.hpp
|
||||||
DESTINATION ${NG_INSTALL_DIR_INCLUDE}/core COMPONENT netgen_devel)
|
DESTINATION ${NG_INSTALL_DIR_INCLUDE}/core COMPONENT netgen_devel)
|
||||||
|
|
||||||
if(ENABLE_CPP_CORE_GUIDELINES_CHECK)
|
if(ENABLE_CPP_CORE_GUIDELINES_CHECK)
|
||||||
|
109
libsrc/core/ranges.hpp
Normal file
109
libsrc/core/ranges.hpp
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
#ifndef NETGEN_CORE_RANGES_HPP
|
||||||
|
#define NETGEN_CORE_RANGES_HPP
|
||||||
|
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
|
namespace ngcore
|
||||||
|
{
|
||||||
|
template<typename Iterator>
|
||||||
|
class AdapterRange
|
||||||
|
{
|
||||||
|
Iterator _begin,_end;
|
||||||
|
public:
|
||||||
|
AdapterRange(Iterator abegin, Iterator aend) : _begin(abegin), _end(aend) { ; }
|
||||||
|
Iterator begin() const { return _begin; }
|
||||||
|
Iterator end() const { return _end; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename FUNC>
|
||||||
|
class FilterAdapter
|
||||||
|
{
|
||||||
|
FUNC f;
|
||||||
|
public:
|
||||||
|
FilterAdapter(FUNC af) : f(af) { ; }
|
||||||
|
FUNC GetFunction() const { return f; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename FUNC, typename Iterator>
|
||||||
|
class FilterIterator
|
||||||
|
{
|
||||||
|
Iterator iter;
|
||||||
|
Iterator end;
|
||||||
|
FUNC f;
|
||||||
|
public:
|
||||||
|
FilterIterator(FUNC af, Iterator aiter, Iterator aend)
|
||||||
|
: f(af), iter(aiter), end(aend)
|
||||||
|
{
|
||||||
|
while(iter!=end && !f(*iter))
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
inline FilterIterator& operator ++()
|
||||||
|
{
|
||||||
|
++iter;
|
||||||
|
while(iter!=end && !f(*iter))
|
||||||
|
++iter;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator !=(FilterIterator other)
|
||||||
|
{
|
||||||
|
return iter != other.iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator ==(FilterIterator other)
|
||||||
|
{
|
||||||
|
return iter == other.iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline decltype(auto) operator *() const
|
||||||
|
{
|
||||||
|
return *iter;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename FUNC>
|
||||||
|
FilterAdapter<FUNC> filter(FUNC f) { return {f}; }
|
||||||
|
|
||||||
|
template<typename Range, typename FUNC>
|
||||||
|
auto operator |(Range&& range, FilterAdapter<FUNC> adapter)
|
||||||
|
-> AdapterRange<FilterIterator<FUNC,decltype(std::begin(range))>>
|
||||||
|
{
|
||||||
|
return {{adapter.GetFunction(),std::begin(range),std::end(range)},
|
||||||
|
{adapter.GetFunction(), std::end(range), std::end(range)}};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename FUNC, typename Iterator>
|
||||||
|
class TransformIterator
|
||||||
|
{
|
||||||
|
FUNC f;
|
||||||
|
Iterator iter;
|
||||||
|
public:
|
||||||
|
TransformIterator(FUNC af, Iterator aiter) : f(af), iter(aiter) { ; }
|
||||||
|
|
||||||
|
TransformIterator& operator++() { ++iter; }
|
||||||
|
bool operator !=(TransformIterator other) { return iter != other.iter; }
|
||||||
|
decltype(auto) operator *() const { return f(*iter); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename FUNC>
|
||||||
|
class TransformAdapter
|
||||||
|
{
|
||||||
|
FUNC f;
|
||||||
|
public:
|
||||||
|
TransformAdapter(FUNC af) : f(af) { ; }
|
||||||
|
FUNC GetFunction() const { return f; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename FUNC>
|
||||||
|
TransformAdapter<FUNC> transform(FUNC f) { return {f}; }
|
||||||
|
|
||||||
|
template<typename Range, typename FUNC>
|
||||||
|
auto operator |(Range&& range, TransformAdapter<FUNC> adapter)
|
||||||
|
-> AdapterRange<TransformIterator<FUNC,decltype(std::begin(range))>>
|
||||||
|
{
|
||||||
|
return {{adapter.GetFunction(), std::begin(range)},
|
||||||
|
{adapter.GetFunction(),std::end(range)}};
|
||||||
|
}
|
||||||
|
} // namespace ngcore
|
||||||
|
|
||||||
|
#endif // NETGEN_CORE_RANGES_HPP
|
@ -27,6 +27,7 @@ endmacro()
|
|||||||
|
|
||||||
add_unit_test(archive archive.cpp)
|
add_unit_test(archive archive.cpp)
|
||||||
add_unit_test(array array.cpp)
|
add_unit_test(array array.cpp)
|
||||||
|
add_unit_test(ranges ranges.cpp)
|
||||||
add_unit_test(symboltable symboltable.cpp)
|
add_unit_test(symboltable symboltable.cpp)
|
||||||
add_unit_test(utils utils.cpp)
|
add_unit_test(utils utils.cpp)
|
||||||
add_unit_test(version version.cpp)
|
add_unit_test(version version.cpp)
|
||||||
|
18
tests/catch/ranges.cpp
Normal file
18
tests/catch/ranges.cpp
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
|
||||||
|
#include "catch.hpp"
|
||||||
|
|
||||||
|
#include <core/array.hpp>
|
||||||
|
#include <core/ranges.hpp>
|
||||||
|
|
||||||
|
using namespace ngcore;
|
||||||
|
|
||||||
|
TEST_CASE("ranges")
|
||||||
|
{
|
||||||
|
Array<int> a { 3, -1, 10, -5 };
|
||||||
|
Array<int> positive { 3, 10 };
|
||||||
|
int i = 0;
|
||||||
|
for(auto pos_val : a | filter([](auto val) { return val >= 0; }))
|
||||||
|
{
|
||||||
|
CHECK(pos_val == positive[i++]);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user