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
|
||||
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
|
||||
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)
|
||||
|
||||
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(array array.cpp)
|
||||
add_unit_test(ranges ranges.cpp)
|
||||
add_unit_test(symboltable symboltable.cpp)
|
||||
add_unit_test(utils utils.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