← Back
Editing: NoneType.hpp
#ifndef PYTHONIC_TYPES_NONE_HPP #define PYTHONIC_TYPES_NONE_HPP #include "pythonic/include/types/NoneType.hpp" #include "pythonic/types/assignable.hpp" #include "pythonic/builtins/id.hpp" #include "pythonic/builtins/bool_.hpp" #include "pythonic/operator_/mod.hpp" PYTHONIC_NS_BEGIN namespace types { /// none_type implementation none_type::none_type() { } intptr_t none_type::id() const { return NONE_ID; } /// none implementation /* Type adapator to simulate an option type * * see http://en.wikipedia.org/wiki/Option_type */ template <class T> none<T, false>::none(none_type const &) : T(), is_none(true) { } template <class T> bool none<T, false>::operator==(none_type const &) const { return is_none; } template <class T> template <class O> bool none<T, false>::operator==(O const &t) const { return !is_none && static_cast<const T &>(*this) == t; } template <class T> bool none<T, false>::operator!=(none_type const &other) const { return !(*this == other); } template <class T> template <class O> bool none<T, false>::operator!=(O const &other) const { return !(*this == other); } template <class T> none<T, false>::operator bool() const { return !is_none && builtins::functor::bool_{}(static_cast<const T &>(*this)); } template <class T> intptr_t none<T, false>::id() const { return is_none ? NONE_ID : builtins::id(static_cast<const T &>(*this)); } template <class T> std::ostream &operator<<(std::ostream &os, none<T, false> const &v) { if (v.is_none) return os << none_type(); else return os << static_cast<T const &>(v); } /* specialization of none for integral types we cannot derive from */ template <class T> none<T, true>::none() : data(), is_none(false) { } template <class T> none<T, true>::none(none_type const &) : data(), is_none(true) { } template <class T> none<T, true>::none(T const &data) : data(data), is_none(false) { } template <class T> bool none<T, true>::operator==(none_type const &) const { return is_none; } template <class T> template <class O> bool none<T, true>::operator==(O const &t) const { return !is_none && data == t; } template <class T> bool none<T, true>::operator!=(none_type const &other) const { return !(*this == other); } template <class T> template <class O> bool none<T, true>::operator!=(O const &other) const { return !(*this == other); } template <class T> T &none<T, true>::operator=(T const &t) { is_none = false; return data = t; } template <class T> intptr_t none<T, true>::id() const { return is_none ? NONE_ID : reinterpret_cast<intptr_t>(&data); } template <class T> T operator+(none<T, true> const &t0, T const &t1) { return t0.data + t1; } template <class T> T operator+(T const &t0, none<T, true> const &t1) { return t0 + t1.data; } template <class T> none<T, true> operator+(none<T, true> const &t0, none<T, true> const &t1) { if (t0.is_none && t1.is_none) return none_type{}; else return {t0.data + t1.data}; } template <class T> bool operator>(none<T, true> const &t0, T const &t1) { return t0.data > t1; } template <class T> bool operator>(T const &t0, none<T, true> const &t1) { return t0 > t1.data; } template <class T> none<bool> operator>(none<T, true> const &t0, none<T, true> const &t1) { if (t0.is_none && t1.is_none) return none_type{}; else return {t0.data > t1.data}; } template <class T> bool operator>=(none<T, true> const &t0, T const &t1) { return t0.data >= t1; } template <class T> bool operator>=(T const &t0, none<T, true> const &t1) { return t0 >= t1.data; } template <class T> none<bool> operator>=(none<T, true> const &t0, none<T, true> const &t1) { if (t0.is_none && t1.is_none) return none_type{}; else return {t0.data >= t1.data}; } template <class T> bool operator<(none<T, true> const &t0, T const &t1) { return t0.data < t1; } template <class T> bool operator<(T const &t0, none<T, true> const &t1) { return t0 < t1.data; } template <class T> none<bool> operator<(none<T, true> const &t0, none<T, true> const &t1) { if (t0.is_none && t1.is_none) return none_type{}; else return {t0.data < t1.data}; } template <class T> bool operator<=(none<T, true> const &t0, T const &t1) { return t0.data <= t1; } template <class T> bool operator<=(T const &t0, none<T, true> const &t1) { return t0 <= t1.data; } template <class T> none<bool> operator<=(none<T, true> const &t0, none<T, true> const &t1) { if (t0.is_none && t1.is_none) return none_type{}; else return {t0.data <= t1.data}; } template <class T> T operator-(none<T, true> const &t0, T const &t1) { return t0.data - t1; } template <class T> T operator-(T const &t0, none<T, true> const &t1) { return t0 - t1.data; } template <class T> none<T, true> operator-(none<T, true> const &t0, none<T, true> const &t1) { if (t0.is_none && t1.is_none) return none_type{}; else return {t0.data - t1.data}; } template <class T> T operator*(none<T, true> const &t0, T const &t1) { return t0.data * t1; } template <class T> T operator*(T const &t0, none<T, true> const &t1) { return t0 * t1.data; } template <class T> none<T, true> operator*(none<T, true> const &t0, none<T, true> const &t1) { if (t0.is_none && t1.is_none) return none_type{}; else return {t0.data * t1.data}; } template <class T> T operator/(none<T, true> const &t0, T const &t1) { return t0.data / t1; } template <class T> T operator/(T const &t0, none<T, true> const &t1) { return t0 / t1.data; } template <class T> none<T, true> operator/(none<T, true> const &t0, none<T, true> const &t1) { if (t0.is_none && t1.is_none) return none_type{}; else return {t0.data / t1.data}; } template <class T0, class T1> decltype(operator_::mod(std::declval<T0>(), std::declval<T1>())) operator%(none<T0, true> const &t0, T1 const &t1) { return operator_::mod(t0.data, t1); } template <class T0, class T1> decltype(operator_::mod(std::declval<T0>(), std::declval<T1>())) operator%(T0 const &t0, none<T1, true> const &t1) { return operator_::mod(t0, t1.data); } template <class T0, class T1> none<decltype(operator_::mod(std::declval<T0>(), std::declval<T1>())), true> operator%(none<T0, true> const &t0, none<T1, true> const &t1) { if (t0.is_none && t1.is_none) return none_type{}; else return {operator_::mod(t0, t1.data)}; } template <class T> template <class T1> none<T, true> &none<T, true>::operator+=(T1 other) { if (!is_none) data += other; return *this; } template <class T> template <class T1> none<T, true> &none<T, true>::operator-=(T1 other) { if (!is_none) data -= other; return *this; } template <class T> template <class T1> none<T, true> &none<T, true>::operator*=(T1 other) { if (!is_none) data *= other; return *this; } template <class T> template <class T1> none<T, true> &none<T, true>::operator/=(T1 other) { if (!is_none) data /= other; return *this; } template <class T> std::ostream &operator<<(std::ostream &os, none<T, true> const &v) { if (v.is_none) return os << none_type(); else return os << v.data; } } PYTHONIC_NS_END #ifdef ENABLE_PYTHON_MODULE PYTHONIC_NS_BEGIN bool from_python<types::none_type>::is_convertible(PyObject *obj) { return obj == Py_None; } types::none_type from_python<types::none_type>::convert(PyObject *obj) { return {}; } PyObject *to_python<types::none_type>::convert(types::none_type) { Py_RETURN_NONE; } template <class T> PyObject *to_python<types::none<T>>::convert(types::none<T> const &n) { if (n.is_none) { Py_RETURN_NONE; } else { return ::to_python(static_cast<T const &>(n)); } } PYTHONIC_NS_END #endif #endif
Save File
Cancel