Created
August 29, 2012 23:34
-
-
Save marionette-of-u/3520406 to your computer and use it in GitHub Desktop.
This file contains hidden or 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 <memory> | |
| #include <utility> | |
| #include <iostream> | |
| #include <gmpxx.h> | |
| namespace cmpxx{ | |
| namespace aux{ | |
| template<class T> | |
| struct expr_wrapper{ | |
| typedef T type; | |
| expr_wrapper(const type &expr_) : expr(expr_){} | |
| type expr; | |
| }; | |
| template<class MPClass> | |
| class mp_wrapper{ | |
| public: | |
| typedef MPClass mp_type; | |
| mp_wrapper() : | |
| value_pointer_(new MPClass) | |
| {} | |
| mp_wrapper(const mp_wrapper &other) : | |
| value_pointer_(new MPClass(*other.value_pointer_.get())) | |
| {} | |
| mp_wrapper(mp_wrapper &&other) : | |
| value_pointer_(nullptr) | |
| { value_pointer_.swap(other.value_pointer_); } | |
| mp_wrapper(MPClass &&value) : | |
| value_pointer_(new MPClass) | |
| { swap_mp_class(value); } | |
| template<class T, class U> | |
| mp_wrapper(const __gmp_expr<T, U> &expr) : | |
| value_pointer_(new MPClass(expr)) | |
| {} | |
| template<class T> | |
| mp_wrapper(const expr_wrapper<T> &wrapped_expr) : | |
| value_pointer_(new MPClass(wrapped_expr.expr)) | |
| {} | |
| mp_wrapper(const std::string &s, int base = 0) : | |
| value_pointer_(new MPClass(s, base)) | |
| {} | |
| mp_wrapper &operator =(const mp_wrapper &other){ | |
| get_raw_value() = other.get_raw_value(); | |
| return *this; | |
| } | |
| mp_wrapper &operator =(mp_wrapper &&other){ | |
| value_pointer_.swap(other.value_pointer_); | |
| other.value_pointer_.reset(nullptr); | |
| return *this; | |
| } | |
| mp_wrapper &operator =(MPClass &&raw_value){ | |
| swap_mp_class(raw_value); | |
| return *this; | |
| } | |
| template<class T, class U> | |
| mp_wrapper &operator =(const __gmp_expr<T, U> &expr){ | |
| *value_pointer_.get() = expr; | |
| return *this; | |
| } | |
| template<class T> | |
| mp_wrapper &operator =(const expr_wrapper<T> &wrapped_expr){ | |
| *value_pointer_.get() = wrapped_expr.expr; | |
| return *this; | |
| } | |
| const MPClass &get_raw_value() const{ | |
| return *value_pointer_.get(); | |
| } | |
| MPClass &get_raw_value(){ | |
| return *value_pointer_.get(); | |
| } | |
| private: | |
| void swap_mp_class(MPClass &value){ | |
| typedef typename std::aligned_storage< | |
| sizeof(MPClass), | |
| std::alignment_of<MPClass>::value | |
| >::type pod_of_mp_class; | |
| std::swap( | |
| *static_cast<pod_of_mp_class*>(static_cast<void*>(value_pointer_.get())), | |
| *static_cast<pod_of_mp_class*>(static_cast<void*>(&value)) | |
| ); | |
| } | |
| std::unique_ptr<MPClass> value_pointer_; | |
| }; | |
| } | |
| } | |
| #define CMPXX_EMPTY_DEFINED | |
| #define CMPXX_DEFINE_OPERATOR_BUILT_IN_TYPE_OVERLOAD_IMPL(op, decl_lhs, type, bigtype) \ | |
| template<class T, class U> \ | |
| cmpxx::aux::expr_wrapper<decltype(__gmp_expr<T, U>() op type())> \ | |
| operator op(decl_lhs cmpxx::aux::mp_wrapper<__gmp_expr<T, U>> &expr, type t){ \ | |
| return expr.get_raw_value() op t; \ | |
| } \ | |
| template<class T, class U> \ | |
| cmpxx::aux::expr_wrapper<decltype(type() op __gmp_expr<T, U>())> \ | |
| operator op(type t, const cmpxx::aux::mp_wrapper<__gmp_expr<T, U>> &expr){ \ | |
| return t op expr.get_raw_value(); \ | |
| } | |
| #define CMPXX_DEFINE_OPERATOR_BUILT_IN_TYPE_OVERLOAD_IMPL_S(op, decl_lhs, t) \ | |
| CMPXX_DEFINE_OPERATOR_BUILT_IN_TYPE_OVERLOAD_IMPL(op, decl_lhs, t, signed long int) | |
| #define CMPXX_DEFINE_OPERATOR_BUILT_IN_TYPE_OVERLOAD_IMPL_U(op, decl_lhs, t) \ | |
| CMPXX_DEFINE_OPERATOR_BUILT_IN_TYPE_OVERLOAD_IMPL(op, decl_lhs, t, unsigned long int) | |
| #define CMPXX_DEFINE_OPERATOR_BUILT_IN_TYPE_OVERLOAD_IMPL_D(op, decl_lhs, t) \ | |
| CMPXX_DEFINE_OPERATOR_BUILT_IN_TYPE_OVERLOAD_IMPL(op, decl_lhs, t, double) | |
| #define CMPXX_DEFINE_OPERATOR_BUILT_IN_TYPE_OVERLOAD_IMPL_LD(op, decl_lhs, t) \ | |
| CMPXX_DEFINE_OPERATOR_BUILT_IN_TYPE_OVERLOAD_IMPL(op, decl_lhs, t, long double) | |
| #define CMPXX_DEFINE_OPERATOR_BUILT_IN_TYPE_OVERLOAD(op, decl_lhs) \ | |
| CMPXX_DEFINE_OPERATOR_BUILT_IN_TYPE_OVERLOAD_IMPL_S(op, decl_lhs, signed char) \ | |
| CMPXX_DEFINE_OPERATOR_BUILT_IN_TYPE_OVERLOAD_IMPL_U(op, decl_lhs, unsigned char) \ | |
| CMPXX_DEFINE_OPERATOR_BUILT_IN_TYPE_OVERLOAD_IMPL_S(op, decl_lhs, signed int) \ | |
| CMPXX_DEFINE_OPERATOR_BUILT_IN_TYPE_OVERLOAD_IMPL_U(op, decl_lhs, unsigned int) \ | |
| CMPXX_DEFINE_OPERATOR_BUILT_IN_TYPE_OVERLOAD_IMPL_S(op, decl_lhs, signed short int) \ | |
| CMPXX_DEFINE_OPERATOR_BUILT_IN_TYPE_OVERLOAD_IMPL_U(op, decl_lhs, unsigned short int) \ | |
| CMPXX_DEFINE_OPERATOR_BUILT_IN_TYPE_OVERLOAD_IMPL_S(op, decl_lhs, signed long int) \ | |
| CMPXX_DEFINE_OPERATOR_BUILT_IN_TYPE_OVERLOAD_IMPL_U(op, decl_lhs, unsigned long int) \ | |
| CMPXX_DEFINE_OPERATOR_BUILT_IN_TYPE_OVERLOAD_IMPL_D(op, decl_lhs, float) \ | |
| CMPXX_DEFINE_OPERATOR_BUILT_IN_TYPE_OVERLOAD_IMPL_D(op, decl_lhs, double) \ | |
| CMPXX_DEFINE_OPERATOR_BUILT_IN_TYPE_OVERLOAD_IMPL_LD(op, decl_lhs, long double) | |
| #define CMPXX_DEFINE_OPERATOR_EXPR_OVERLOAD(op, decl_lhs) \ | |
| template<class T, class U, class V, class W> \ | |
| cmpxx::aux::expr_wrapper<decltype(__gmp_expr<T, U>() op __gmp_expr<V, W>())> \ | |
| operator op( \ | |
| decl_lhs cmpxx::aux::mp_wrapper<__gmp_expr<T, U>> &l, \ | |
| const cmpxx::aux::mp_wrapper<__gmp_expr<V, W>> &r \ | |
| ){ return l.get_raw_value() op r.get_raw_value(); } \ | |
| template<class T, class U, class V, class W> \ | |
| cmpxx::aux::expr_wrapper<decltype(__gmp_expr<T, U>() op __gmp_expr<V, W>())> \ | |
| operator op( \ | |
| decl_lhs cmpxx::aux::expr_wrapper<__gmp_expr<T, U>> &l, \ | |
| const cmpxx::aux::expr_wrapper<__gmp_expr<V, W>> &r \ | |
| ){ return l.expr op r.expr; } \ | |
| template<class T, class U, class V, class W> \ | |
| cmpxx::aux::expr_wrapper<decltype(__gmp_expr<T, U>() op __gmp_expr<V, W>())> \ | |
| operator op( \ | |
| decl_lhs cmpxx::aux::mp_wrapper<__gmp_expr<T, U>> &l, \ | |
| const cmpxx::aux::expr_wrapper<__gmp_expr<V, W>> &r \ | |
| ){ return l.get_raw_value() op r.expr; } \ | |
| template<class T, class U, class V, class W> \ | |
| cmpxx::aux::expr_wrapper<decltype(__gmp_expr<T, U>() op __gmp_expr<V, W>())> \ | |
| operator op( \ | |
| const cmpxx::aux::expr_wrapper<__gmp_expr<T, U>> &l, \ | |
| const cmpxx::aux::mp_wrapper<__gmp_expr<V, W>> &r \ | |
| ){ return l.expr op r.get_raw_value(); } | |
| #define CMPXX_DEFINE_OPERATOR_OVERLOAD(op, decl_lhs) \ | |
| CMPXX_DEFINE_OPERATOR_EXPR_OVERLOAD(op, decl_lhs) \ | |
| CMPXX_DEFINE_OPERATOR_BUILT_IN_TYPE_OVERLOAD(op, decl_lhs) | |
| #define CMPXX_DEFINE_BOOLIAN_OPERATOR_OVERLOAD(op) \ | |
| CMPXX_DEFINE_OPERATOR_EXPR_OVERLOAD(op, const) \ | |
| CMPXX_DEFINE_OPERATOR_BUILT_IN_TYPE_OVERLOAD(op, const) | |
| CMPXX_DEFINE_OPERATOR_OVERLOAD(+, const); | |
| CMPXX_DEFINE_OPERATOR_OVERLOAD(-, const); | |
| CMPXX_DEFINE_OPERATOR_OVERLOAD(*, const); | |
| CMPXX_DEFINE_OPERATOR_OVERLOAD(/, const); | |
| CMPXX_DEFINE_OPERATOR_OVERLOAD(%, const); | |
| //CMPXX_DEFINE_OPERATOR_OVERLOAD(+=, CMPXX_EMPTY_DEFINED); | |
| //CMPXX_DEFINE_OPERATOR_OVERLOAD(-=, CMPXX_EMPTY_DEFINED); | |
| //CMPXX_DEFINE_OPERATOR_OVERLOAD(*=, CMPXX_EMPTY_DEFINED); | |
| //CMPXX_DEFINE_OPERATOR_OVERLOAD(/=, CMPXX_EMPTY_DEFINED); | |
| //CMPXX_DEFINE_OPERATOR_OVERLOAD(%=, CMPXX_EMPTY_DEFINED); | |
| CMPXX_DEFINE_BOOLIAN_OPERATOR_OVERLOAD(<); | |
| CMPXX_DEFINE_BOOLIAN_OPERATOR_OVERLOAD(>); | |
| CMPXX_DEFINE_BOOLIAN_OPERATOR_OVERLOAD(<=); | |
| CMPXX_DEFINE_BOOLIAN_OPERATOR_OVERLOAD(>=); | |
| CMPXX_DEFINE_BOOLIAN_OPERATOR_OVERLOAD(==); | |
| CMPXX_DEFINE_BOOLIAN_OPERATOR_OVERLOAD(!=); | |
| namespace cmpxx{ | |
| typedef aux::mp_wrapper<mpz_class> integer; | |
| typedef aux::mp_wrapper<mpq_class> rational; | |
| } | |
| #include <typeinfo> | |
| int main(){ | |
| cmpxx::integer a(11); | |
| std::cout << typeid(a * a + a * a).name() << "\n"; | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment