#include #include #include #include #include #include #include // // Functions // struct mod2 : public std::unary_function { int operator()(int x) const { return x % 2; } }; struct mod3 : public std::unary_function { int operator()(int x) const { return x % 3; } }; struct mod4 : public std::unary_function { int operator()(int x) const { return x % 4; } }; // // Base class foo // struct foo { std::vector data_m; foo() : data_m() {} int& insert(int x) { data_m.push_back(x); return data_m.back(); } template std::list > match(const typename trans_T::result_type& pattern, const trans_T& trans = trans_T()) const { std::list > results; for (auto it = data_m.begin(); it != data_m.end(); ++it) { auto p = trans(*it); if (pattern == p) { results.push_back(std::make_pair(p, *it)); } } return results; } }; // // Derived class bar // template struct bar : public base_T { typedef base_T base_type; typedef std::multimap index_type; index_type index_m; bar(const trans_T& trans = trans_T()) : base_type(), index_m() {} int& insert(int x, const trans_T& trans = trans_T()) { return index_m.insert(typename index_type::value_type(trans(x), base_type::insert(x)))->second; } std::pair match(const typename trans_T::result_type& pattern, const trans_T& trans = trans_T()) const { return index_m.equal_range(pattern); } template decltype(base_type().match(typename xtrans_T::result_type(), xtrans_T())) match(const typename xtrans_T::result_type& pattern, const xtrans_T& xtrans = xtrans_T()) const { return base_type::match(pattern, xtrans); } }; // // Begin/end functions present in Boost but not in GCC // template iter_T begin(const std::pair& range) { return range.first; } template iter_T end(const std::pair& range) { return range.second; } // // Main // int main(const int argc, const char** argv) { using std::cout; using std::endl; bar, mod3> baz; /// /// Insert some numbers /// for (int i = 0; i < 20; ++i) { baz.insert(i); } for (int i = 0; i < 5; ++i) { cout << "i = " << i << endl; /// /// Try to match with different functions /// auto baz_match_mod2 = baz.match(i, mod2()); cout << "mod2:"; for (auto it = begin(baz_match_mod2); it != end(baz_match_mod2); ++it) { assert(it->first == i); cout << ' ' << it->second; } cout << endl; auto baz_match_mod3 = baz.match(i, mod3()); cout << "mod3:"; for (auto it = begin(baz_match_mod3); it != end(baz_match_mod3); ++it) { assert(it->first == i); cout << ' ' << it->second; } cout << endl; auto baz_match_mod4 = baz.match(i, mod4()); cout << "mod4:"; for (auto it = begin(baz_match_mod4); it != end(baz_match_mod4); ++it) { assert(it->first == i); cout << ' ' << it->second; } cout << endl; } return 0; }