Skip to content

Instantly share code, notes, and snippets.

@gimKondo
Created February 4, 2014 16:58
Show Gist options
  • Save gimKondo/8807755 to your computer and use it in GitHub Desktop.
Save gimKondo/8807755 to your computer and use it in GitHub Desktop.
#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