← Back
Editing: NoneType.hpp
#ifndef PYTHONIC_INCLUDE_TYPES_NONE_HPP #define PYTHONIC_INCLUDE_TYPES_NONE_HPP #include "pythonic/include/types/assignable.hpp" #include "pythonic/include/operator_/mod.hpp" #include <ostream> PYTHONIC_NS_BEGIN namespace types { static const intptr_t NONE_ID = 0x1331; struct none_type { none_type(); intptr_t id() const; }; std::ostream &operator<<(std::ostream &os, none_type const &) { return os << "None"; } template <class T, bool is_fundamental = std::is_fundamental<T>::value> struct none; /* Type adapator to simulate an option type * * see http://en.wikipedia.org/wiki/Option_type */ template <class T> struct none<T, false> : T { bool is_none; // set to true if the type is none none(none_type const &); none() : T(), is_none{true} { } none(none const &other) = default; none(T const &arg) : T(arg), is_none(false) { } template <class OT> none(OT const &arg) : none(T(arg)) { } bool operator==(none_type const &) const; template <class O> bool operator==(O const &t) const; bool operator!=(none_type const &) const; template <class O> bool operator!=(O const &t) const; explicit operator bool() const; intptr_t id() const; template <class T0> friend std::ostream &operator<<(std::ostream &os, none<T0, false> const &); }; /* specialization of none for integral types we cannot derive from */ template <class P, class T> struct none_data { explicit operator bool() const { return !static_cast<P const *>(this)->is_none && static_cast<P const *>(this)->data; } operator T() const { return static_cast<P const *>(this)->data; } }; template <class P> struct none_data<P, bool> { operator bool() const { return !static_cast<P const *>(this)->is_none && static_cast<P const *>(this)->data; } }; template <class T> struct none<T, true> : none_data<none<T, true>, T> { T data; template <class T1> friend std::ostream &operator<<(std::ostream &, none<T1, true> const &); template <class T1> friend T1 operator+(none<T1, true> const &t0, T1 const &t1); template <class T1> friend T1 operator+(T1 const &t0, none<T1, true> const &t1); template <class T1> friend none<T1, true> operator+(none<T1, true> const &t0, none<T1, true> const &t1); template <class T1> friend bool operator>(none<T1, true> const &t0, T1 const &t1); template <class T1> friend bool operator>(T1 const &t0, none<T1, true> const &t1); template <class T1> friend none<bool> operator>(none<T1, true> const &t0, none<T1, true> const &t1); template <class T1> friend bool operator>=(none<T1, true> const &t0, T1 const &t1); template <class T1> friend bool operator>=(T1 const &t0, none<T1, true> const &t1); template <class T1> friend none<bool> operator>=(none<T1, true> const &t0, none<T1, true> const &t1); template <class T1> friend bool operator<(none<T1, true> const &t0, T1 const &t1); template <class T1> friend bool operator<(T1 const &t0, none<T1, true> const &t1); template <class T1> friend none<bool> operator<(none<T1, true> const &t0, none<T1, true> const &t1); template <class T1> friend bool operator<=(none<T1, true> const &t0, T1 const &t1); template <class T1> friend bool operator<=(T1 const &t0, none<T1, true> const &t1); template <class T1> friend none<bool> operator<=(none<T1, true> const &t0, none<T1, true> const &t1); template <class T1> friend T1 operator-(none<T1, true> const &t0, T1 const &t1); template <class T1> friend T1 operator-(T1 const &t0, none<T1, true> const &t1); template <class T1> friend none<T1, true> operator-(none<T1, true> const &t0, none<T1, true> const &t1); template <class T1> friend T1 operator*(none<T1, true> const &t0, T1 const &t1); template <class T1> friend T1 operator*(T1 const &t0, none<T1, true> const &t1); template <class T1> friend none<T1, true> operator*(none<T1, true> const &t0, none<T1, true> const &t1); template <class T1> friend T1 operator/(none<T1, true> const &t0, T1 const &t1); template <class T1> friend T1 operator/(T1 const &t0, none<T1, true> const &t1); template <class T1> friend none<T1, true> operator/(none<T1, true> const &t0, none<T1, true> const &t1); template <class T1> none &operator+=(T1 other); template <class T1> none &operator-=(T1 other); template <class T1> none &operator*=(T1 other); template <class T1> none &operator/=(T1 other); public: bool is_none; none(); none(none_type const &); none(T const &data); bool operator==(none_type const &) const; template <class O> bool operator==(O const &t) const; bool operator!=(none_type const &) const; template <class O> bool operator!=(O const &t) const; T &operator=(T const &t); intptr_t id() const; template <class T1> operator none<T1, true>() { if (is_none) return {none_type{}}; else return {static_cast<T1>(data)}; } }; template <class T> T operator+(none<T, true> const &t0, T const &t1); template <class T> T operator+(T const &t0, none<T, true> const &t1); template <class T> none<T, true> operator+(none<T, true> const &t0, none<T, true> const &t1); template <class T> bool operator>(none<T, true> const &t0, T const &t1); template <class T> bool operator>(T const &t0, none<T, true> const &t1); template <class T> none<bool> operator>(none<T, true> const &t0, none<T, true> const &t1); template <class T> bool operator>=(none<T, true> const &t0, T const &t1); template <class T> bool operator>=(T const &t0, none<T, true> const &t1); template <class T> none<bool> operator>=(none<T, true> const &t0, none<T, true> const &t1); template <class T> bool operator<(none<T, true> const &t0, T const &t1); template <class T> bool operator<(T const &t0, none<T, true> const &t1); template <class T> none<bool> operator<(none<T, true> const &t0, none<T, true> const &t1); template <class T> bool operator<=(none<T, true> const &t0, T const &t1); template <class T> bool operator<=(T const &t0, none<T, true> const &t1); template <class T> none<bool> operator<=(none<T, true> const &t0, none<T, true> const &t1); template <class T> T operator-(none<T, true> const &t0, T const &t1); template <class T> T operator-(T const &t0, none<T, true> const &t1); template <class T> none<T, true> operator-(none<T, true> const &t0, none<T, true> const &t1); template <class T> T operator*(none<T, true> const &t0, T const &t1); template <class T> T operator*(T const &t0, none<T, true> const &t1); template <class T> none<T, true> operator*(none<T, true> const &t0, none<T, true> const &t1); template <class T> T operator/(none<T, true> const &t0, T const &t1); template <class T> T operator/(T const &t0, none<T, true> const &t1); template <class T> none<T, true> operator/(none<T, true> const &t0, none<T, true> const &t1); template <class T0, class T1> decltype(operator_::mod(std::declval<T0>(), std::declval<T1>())) operator%(none<T0, true> const &t0, T1 const &t1); template <class T0, class T1> decltype(operator_::mod(std::declval<T0>(), std::declval<T1>())) operator%(T0 const &t0, none<T1, true> const &t1); 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); template <class T> std::ostream &operator<<(std::ostream &os, none<T, true> const &v); template <class T> struct is_none { static const bool value = false; }; template <class T> struct is_none<none<T>> { static const bool value = true; }; } template <class T> struct assignable<types::none<T>> { using type = types::none<typename assignable<T>::type>; }; PYTHONIC_NS_END namespace std { /* std::get overload */ template <size_t I, class T0> auto get(pythonic::types::none<T0> const &t) -> decltype(std::get<I>((T0 const &)t)); template <size_t I, class T0> struct tuple_element<I, pythonic::types::none<T0>> { using type = typename std::tuple_element<I, T0>::type; }; } /* type inference stuff { */ #include "pythonic/include/types/combined.hpp" template <class T0, class T1> struct __combined<pythonic::types::none<T0>, T1> { static_assert(!pythonic::types::is_none<T1>::value, "none of none should'nt exist"); using type = pythonic::types::none<typename __combined<T0, T1>::type>; }; template <class T0, class T1> struct __combined<T1, pythonic::types::none<T0>> { static_assert(!pythonic::types::is_none<T0>::value, "none of none should'nt exist"); using type = pythonic::types::none<typename __combined<T0, T1>::type>; }; template <class T0, class T1> struct __combined<pythonic::types::none<T1>, pythonic::types::none<T0>> { static_assert(!pythonic::types::is_none<T0>::value, "none of none shouldn't exist"); static_assert(!pythonic::types::is_none<T1>::value, "none of none shouldn't exist"); using type = pythonic::types::none<typename __combined<T0, T1>::type>; }; template <class T> struct __combined<pythonic::types::none_type, T> { static_assert(!pythonic::types::is_none<T>::value, "none of none shouldn't exist"); using type = pythonic::types::none<T>; }; template <class T> struct __combined<pythonic::types::none_type, pythonic::types::none<T>> { static_assert(!pythonic::types::is_none<T>::value, "none of none shouldn't exist"); using type = pythonic::types::none<T>; }; template <class T> struct __combined<T, pythonic::types::none_type> { static_assert(!pythonic::types::is_none<T>::value, "none of none shouldn't exist"); using type = pythonic::types::none<T>; }; template <class T> struct __combined<pythonic::types::none<T>, pythonic::types::none_type> { static_assert(!pythonic::types::is_none<T>::value, "none of none shouldn't exist"); using type = pythonic::types::none<T>; }; template <> struct __combined<pythonic::types::none_type, pythonic::types::none_type> { using type = pythonic::types::none_type; }; /* } */ #ifdef ENABLE_PYTHON_MODULE #include "pythonic/python/core.hpp" PYTHONIC_NS_BEGIN template <> struct to_python<types::none_type> { static PyObject *convert(types::none_type); }; template <class T> struct to_python<types::none<T>> { static PyObject *convert(types::none<T> const &n); }; template <> struct from_python<types::none_type> { static bool is_convertible(PyObject *obj); static types::none_type convert(PyObject *obj); }; PYTHONIC_NS_END #endif #endif
Save File
Cancel