프로그래밍 검색 블로그

C++ 컬렉션 필터링 본문

C++ 유틸

C++ 컬렉션 필터링

코딩조무사 2017. 10. 7. 16:49

아직 ranges가 사용중인 컴파일러에서 컴파일이 불가능해서 만들었다

ranges가 컴파일이 가능한 최신 컴파일러라면 ranges를 사용할 것

여기 -> https://github.com/ericniebler/range-v3 



1
2
3
4
    template<typename _Collection>
    using collection_value_type =
    typename std::remove_const<
    typename std::remove_reference<_Collection>::type>::type::value_type;
cs



함수의 인자로 들어온 collection에서 value_type만 추출 


1
2
3
4
5
6
7
8
    template<typename _Collection, typename _Func>
    inline auto filter(_Collection&& collection, _Func&& predicate) -> std::vector< collection_value_type<_Collection> > {
        std::vector<collection_value_type<_Collection>> destination;
        
        filterTo(std::forward<_Collection>(collection), destination, std::forward<_Func>(predicate));
        
        return destination;
    }
cs



인자로 컬렉션과 함수를 받아서 vector를 반환하는데 filterTo로 넘긴다 

1
2
3
4
5
6
7
8
9
10
    template<typename _Collection, typename _InsertCollection, typename _Func>
    void filterTo(_Collection&& collection, _InsertCollection& destination, _Func&& predicate) {
        auto insert_iterator = std::back_inserter(destination);
        for(const auto& e : collection){
            if(predicate(e)){
                *insert_iterator = e;
                ++insert_iterator;
            }
        }
    }
cs


filterTo는 컬렉션을 순회하면서 

predicate가 참이되면 두번째 인자에 집어넣는다. 




합친것

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <functional>
#include <type_traits>
#include <vector>
namespace Collections {
    
    template<typename _Collection>
    using collection_value_type =
    typename std::remove_const<
    typename std::remove_reference<_Collection>::type>::type::value_type;
 
    template<typename _Collection, typename _InsertCollection, typename _Func>
    void filterTo(_Collection&& collection, _InsertCollection& destination, _Func&& predicate) {
        auto insert_iterator = std::back_inserter(destination);
        for(const auto& e : collection){
            if(predicate(e)){
                *insert_iterator = e;
                ++insert_iterator;
            }
        }
    }
    
    template<typename _Collection, typename _Func>
    inline auto filter(_Collection&& collection, _Func&& predicate) -> std::vector< collection_value_type<_Collection> > {
        std::vector<collection_value_type<_Collection>> destination;
        
        filterTo(std::forward<_Collection>(collection), destination, std::forward<_Func>(predicate));
        
        return destination;
    }
}
cs





테스트

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <list>
#include <iostream>
using namespace std;
 
int main(){
 
    
    list<int> flat = {1,2,3,4,5,6,7,8,9,0};
    
    auto out = Collections::filter(flat, [](int e){
        return e <= 3;
    });
    
    for(auto& e : out){
        cout << e << endl;
    }
}
cs


'C++ 유틸' 카테고리의 다른 글

함수가 끝날때 같이 해제하기 defer  (0) 2017.10.06
시간 관련 API  (0) 2017.10.04
stringprintf string반환 sprintf 2  (0) 2017.10.04
stringprintf string반환 sprintf 1  (0) 2017.10.04
C++ Traits  (0) 2017.10.03
Comments