এখানে একটি দ্রুত অপেক্ষাকৃত ন্যূনতম filter
ফাংশন।
এটি একটি শিকারী লাগে। এটি একটি ফাংশন অবজেক্ট প্রদান করে যা পুনরাবৃত্ত হয়।
এটি একটি পুনরুক্তি করে যা একটি for(:)
লুপে ব্যবহার করা যায় ।
template<class It>
struct range_t {
It b, e;
It begin() const { return b; }
It end() const { return e; }
bool empty() const { return begin()==end(); }
};
template<class It>
range_t<It> range( It b, It e ) { return {std::move(b), std::move(e)}; }
template<class It, class F>
struct filter_helper:range_t<It> {
F f;
void advance() {
while(true) {
(range_t<It>&)*this = range( std::next(this->begin()), this->end() );
if (this->empty())
return;
if (f(*this->begin()))
return;
}
}
filter_helper(range_t<It> r, F fin):
range_t<It>(r), f(std::move(fin))
{
while(true)
{
if (this->empty()) return;
if (f(*this->begin())) return;
(range_t<It>&)*this = range( std::next(this->begin()), this->end() );
}
}
};
template<class It, class F>
struct filter_psuedo_iterator {
using iterator_category=std::input_iterator_tag;
filter_helper<It, F>* helper = nullptr;
bool m_is_end = true;
bool is_end() const {
return m_is_end || !helper || helper->empty();
}
void operator++() {
helper->advance();
}
typename std::iterator_traits<It>::reference
operator*() const {
return *(helper->begin());
}
It base() const {
if (!helper) return {};
if (is_end()) return helper->end();
return helper->begin();
}
friend bool operator==(filter_psuedo_iterator const& lhs, filter_psuedo_iterator const& rhs) {
if (lhs.is_end() && rhs.is_end()) return true;
if (lhs.is_end() || rhs.is_end()) return false;
return lhs.helper->begin() == rhs.helper->begin();
}
friend bool operator!=(filter_psuedo_iterator const& lhs, filter_psuedo_iterator const& rhs) {
return !(lhs==rhs);
}
};
template<class It, class F>
struct filter_range:
private filter_helper<It, F>,
range_t<filter_psuedo_iterator<It, F>>
{
using helper=filter_helper<It, F>;
using range=range_t<filter_psuedo_iterator<It, F>>;
using range::begin; using range::end; using range::empty;
filter_range( range_t<It> r, F f ):
helper{{r}, std::forward<F>(f)},
range{ {this, false}, {this, true} }
{}
};
template<class F>
auto filter( F&& f ) {
return [f=std::forward<F>(f)](auto&& r)
{
using std::begin; using std::end;
using iterator = decltype(begin(r));
return filter_range<iterator, std::decay_t<decltype(f)>>{
range(begin(r), end(r)), f
};
};
};
শর্ট কাট নিলাম। একটি বাস্তব গ্রন্থাগারকে সত্যিকারের for(:)
পুনরাবৃত্তি করা উচিত, আমি যে-যোগ্য সিউডো-ফ্যাসাডকে করেছিলাম তা নয়।
ব্যবহারের স্থানে, এটি দেখতে এটির মতো দেখাচ্ছে:
int main()
{
std::vector<int> test = {1,2,3,4,5};
for( auto i: filter([](auto x){return x%2;})( test ) )
std::cout << i << '\n';
}
যা বেশ সুন্দর, এবং প্রিন্ট
1
3
5
সরাসরি উদাহরণ ।
রেঞ্জেস 3 নামক সি ++ তে প্রস্তাবিত সংযোজন রয়েছে যা এই ধরণের জিনিস এবং আরও অনেক কিছু করে। boost
এছাড়াও ফিল্টার ব্যাপ্তি / পুনরাবৃত্তি উপলব্ধ। বুস্টের এমন সহায়কও রয়েছে যা উপরের লেখাকে আরও ছোট করে তোলে।
std::copy_if
, তবে নির্বাচনগুলি অলস নয়