Created
February 4, 2014 16:58
-
-
Save gimKondo/8807755 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <vector> | |
#include <iostream> | |
#include <memory> | |
#include <functional> | |
#include <type_traits> | |
// interface of filtered object | |
template <typename SRC_E> struct IFiltered | |
{ | |
~IFiltered() {} | |
virtual std::vector<SRC_E> Get() const = 0; | |
virtual std::shared_ptr<IFiltered> Clone() const = 0; | |
}; | |
// concrete filtered object | |
template <typename SRC_E, typename FILTER> struct FilteredConcrete : IFiltered<SRC_E> | |
{ | |
FilteredConcrete(const std::vector<SRC_E>& srcArr, FILTER filter) | |
: srcArr_(srcArr), filter_(filter) | |
{} | |
std::vector<SRC_E> Get() const | |
{ | |
std::vector<SRC_E> ret; | |
for (int i = 0; i < srcArr_.size(); ++i) | |
{ | |
if (filter_(srcArr_[i])) { | |
ret.push_back(srcArr_[i]); | |
} | |
} | |
return ret; | |
} | |
virtual std::shared_ptr<IFiltered<SRC_E>> Clone() const { return std::make_shared<FilteredConcrete>(*this); } | |
std::vector<SRC_E> srcArr_; | |
FILTER filter_; | |
}; | |
// composite filtered object | |
template <typename SRC_E, typename FILTER> struct FilteredComposite : IFiltered<SRC_E> | |
{ | |
typedef IFiltered<SRC_E> ELM; | |
FilteredComposite(const ELM& elm, FILTER filter) | |
: element_(elm.Clone()), filter_(filter) | |
{} | |
std::vector<SRC_E> Get() const | |
{ | |
const auto arr = element_->Get(); | |
std::vector<SRC_E> ret; | |
for (int i = 0; i < arr.size(); ++i) | |
{ | |
if (filter_(arr[i])) { | |
ret.push_back(arr[i]); | |
} | |
} | |
return ret; | |
} | |
virtual std::shared_ptr<IFiltered<SRC_E>> Clone() const { return std::make_shared<FilteredComposite>(*this); } | |
std::shared_ptr<ELM> element_; | |
FILTER filter_; | |
}; | |
// operator that creates filtered object | |
template <typename SRC_E, typename FILTER> | |
FilteredConcrete<SRC_E, FILTER> operator , ( std::vector<SRC_E>& src, FILTER filter) | |
{ | |
return FilteredConcrete<SRC_E, FILTER>(src, filter); | |
} | |
// operator that creates composite filtered object | |
template <typename SRC_E, typename FILTER> | |
FilteredComposite<SRC_E, FILTER> operator , ( const IFiltered<SRC_E>& elm, FILTER filter) | |
{ | |
return FilteredComposite<SRC_E, FILTER>(elm, filter); | |
} | |
// extract filtered list | |
template <typename PRED, typename SRC_E> | |
std::vector<int> operator | ( PRED pred, const IFiltered<SRC_E>& capt) | |
{ | |
std::vector<int> ret; | |
std::vector<SRC_E> filtered = capt.Get(); | |
for (int i = 0; i < filtered.size(); ++i) | |
{ | |
ret.push_back(pred(filtered[i])); | |
} | |
return ret; | |
} | |
// object for sample | |
struct Widget | |
{ | |
Widget(int a, int b) : a_(a), b_(b) {} | |
Widget() : a_(0), b_(0) {} | |
int a_; | |
int b_; | |
}; | |
// test | |
int main() | |
{ | |
std::vector<Widget> widgets; | |
widgets.push_back(Widget( 1, 2)); | |
widgets.push_back(Widget( 2, 3)); | |
widgets.push_back(Widget( 4, 2)); | |
widgets.push_back(Widget( 7, 3)); | |
widgets.push_back(Widget( 9, 3)); | |
widgets.push_back(Widget( 8, 5)); | |
widgets.push_back(Widget( 8, 3)); | |
std::vector<int> nums = [](const Widget& o) { return o.a_ * o.a_; } | |
| (widgets, [](const Widget& o) { return o.a_ % 2 == 0; }, [](const Widget& o) { return 3 <= o.b_; }); | |
std::cout << "output" << std::endl; | |
for(int i = 0; i < nums.size(); ++i) | |
{ | |
std::cout << i << ":" << nums[i] << std::endl; | |
} | |
return 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment