Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include "boost/static_assert.hpp"
- #include <boost/type_traits.hpp>
- #include <boost/utility.hpp>
- #include <boost/any.hpp>
- using namespace std;
- /// Base class for all cut functors (toy classifier of ints)
- struct Cut {
- virtual bool cut(int n) const = 0;
- };
- // Various cut functors operating on ints
- struct Odd : public Cut {
- bool cut(int n) const { return n % 2 == 1; }
- };
- struct Even : public Cut {
- bool cut(int n) const { return n % 2 == 0; }
- };
- struct Less : public Cut {
- Less(int n) : val(n) { }
- bool cut(int n) const { return n < val; }
- int val;
- };
- struct LessEq : public Cut {
- LessEq(int n) : val(n) { }
- bool cut(int n) const { return n <= val; }
- int val;
- };
- // AND, OR and NOT objects for combining cuts
- template <typename CUT1, typename CUT2>
- struct CutsOr : public Cut {
- CutsOr(const CUT1& c1, const CUT2& c2) : cut1(c1), cut2(c2) { }
- bool cut(int n) const { return cut1.cut(n) || cut2.cut(n); }
- CUT1 cut1;
- CUT2 cut2;
- BOOST_STATIC_ASSERT((boost::is_base_of<Cut, CUT1>::value && boost::is_base_of<Cut, CUT2>::value));
- };
- template <typename CUT1, typename CUT2>
- struct CutsAnd : public Cut {
- CutsAnd(const CUT1& c1, const CUT2& c2) : cut1(c1), cut2(c2) { }
- bool cut(int n) const { return cut1.cut(n) && cut2.cut(n); }
- CUT1 cut1;
- CUT2 cut2;
- BOOST_STATIC_ASSERT((boost::is_base_of<Cut, CUT1>::value && boost::is_base_of<Cut, CUT2>::value));
- };
- template <typename CUT>
- struct CutInvert : public Cut {
- CutInvert(const CUT& c1) : poscut(c1) { }
- bool cut(int n) const { return !poscut.cut(n); }
- CUT poscut;
- BOOST_STATIC_ASSERT((boost::is_base_of<Cut, CUT>::value));
- };
- // operator &&, operator ||, and operator ! overloads
- //
- // The enable_if complexity is needed to avoid too-global template type matching;
- // the code below is equivalent to simply
- //
- // template <typename CUT1, typename CUT2>
- // CutsAnd<CUT1,CUT2> operator && (const CUT1& a, const CUT2& b) { ... }
- //
- // template <typename CUT1, typename CUT2>
- // CutsAnd<CUT1,CUT2> operator || (const CUT1& a, const CUT2& b) { ... }
- //
- // template <typename CUT>
- // CutInvert<CUT> operator ! (const CUT& c) { ... }
- template <typename CUT1, typename CUT2>
- typename boost::enable_if_c<
- boost::is_base_of<Cut, CUT1>::value && boost::is_base_of<Cut, CUT2>::value,
- CutsAnd<CUT1,CUT2>
- >::type
- operator && (const CUT1& a, const CUT2& b) {
- return CutsAnd<CUT1,CUT2>(a,b);
- }
- template <typename CUT1, typename CUT2>
- typename boost::enable_if_c<
- boost::is_base_of<Cut, CUT1>::value && boost::is_base_of<Cut, CUT2>::value,
- CutsOr<CUT1,CUT2>
- >::type
- operator || (const CUT1& a, const CUT2& b) {
- return CutsOr<CUT1,CUT2>(a,b);
- }
- template <typename CUT>
- typename boost::enable_if_c<
- boost::is_base_of<Cut, CUT>::value,
- CutInvert<CUT>
- >::type
- operator ! (const CUT& c) {
- return CutInvert<CUT>(c);
- }
- //////////////////////////////////////////
- int main() {
- const Cut& c1 = CutsAnd<Odd,Less>(Odd(), Less(5));
- const auto c2 = Odd() && Less(5);
- const auto c3 = c2 || Even();
- const auto c4 = (Odd() && Less(5)) || Even();
- const auto c5 = !( (Odd() && Less(5)) || Even() );
- for (int i = 0; i < 10; ++i) {
- cout << i << " ";
- cout << ((c1.cut(i)) ? "X" : " ");
- cout << ((c2.cut(i)) ? "X" : " ");
- cout << ((c3.cut(i)) ? "X" : " ");
- cout << ((c4.cut(i)) ? "X" : " ");
- cout << ((c5.cut(i)) ? "X" : " ");
- cout << endl;
- }
- return 0;
- }
- // Output:
- // andy@duality:~/.../cxxdev/logic$ g++ logic.cc -o logic -std=c++11
- // andy@duality:~/.../cxxdev/logic$ ./logic
- // 0 XX
- // 1 XXXX
- // 2 XX
- // 3 XXXX
- // 4 XX
- // 5 X
- // 6 XX
- // 7 X
- // 8 XX
- // 9 X
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement