5 #ifndef FSC_POLY_TYPE_HEADER
6 #define FSC_POLY_TYPE_HEADER
8 #include "boost_any.hpp"
9 #include "fsc_except.hpp"
16 #include <type_traits>
28 static typename std::enable_if<std::is_convertible<U, T>::value, T>::type from(U
const & u) {
32 static typename std::enable_if<!std::is_convertible<U, T>::value, T>::type from(U
const &) {
33 throw fsc::O__o(
"poly_type error: type '" + std::string(
typeid(U).name()) +
"' is not convertible to type '" + std::string(
typeid(T).name()) +
"'");
46 template<
typename T,
typename U>
48 static constexpr
bool value =
true;
55 struct drop_casts<std::initializer_list<char>, U> {
56 static constexpr
bool value =
false;
59 struct drop_casts<std::allocator<char>, U> {
60 static constexpr
bool value =
false;
63 struct drop_casts<const char*, U> {
64 static constexpr
bool value =
false;
70 poly_type(T
const & t): any(t) {}
71 poly_type(
char const * t): any(std::string(t)) {}
73 template<typename T, typename enable = std::enable_if_t<drop_casts<T, void>::value>>
75 if(type() ==
typeid(
int)) {
76 return detail::convert<T>::from(boost::any_cast<int>(any));
78 if(type() ==
typeid(
double)) {
79 return detail::convert<T>::from(boost::any_cast<double>(any));
81 if(type() ==
typeid(
bool)) {
82 return detail::convert<T>::from(boost::any_cast<bool>(any));
84 if(type() ==
typeid(std::string)) {
85 return detail::convert<T>::from(boost::any_cast<std::string>(any));
91 void operator=(T
const & t){
94 void operator=(
const char * t) {
97 void operator=(poly_type
const & t){
103 poly_type & operator+=(T
const & t) {
104 return (*
this) += poly_type(t);
106 poly_type & operator+=(
char const * t) {
107 return (*
this)+=std::string(t);
109 poly_type & operator+=(poly_type
const & t) {
110 if(type() ==
typeid(std::string)) {
111 std::string as = (*this);
114 }
else if(type() ==
typeid(
double) or t.type() ==
typeid(double)) {
127 poly_type & operator-=(T
const & t) {
128 return (*
this) -= poly_type(t);
130 poly_type & operator-=(poly_type
const & t) {
131 if(type() ==
typeid(
double) or t.type() ==
typeid(double)) {
144 poly_type & operator*=(T
const & t) {
145 return (*
this) *= poly_type(t);
147 poly_type & operator*=(poly_type
const & t) {
148 if(type() ==
typeid(
double) or t.type() ==
typeid(double)) {
161 poly_type & operator/=(T
const & t) {
162 return (*
this) /= poly_type(t);
164 poly_type & operator/=(poly_type
const & t) {
172 std::type_info
const & type()
const {
176 void print(S & os)
const {
177 if(type() ==
typeid(
bool)) {
178 os << boost::any_cast<bool>(any);
180 if(type() ==
typeid(int)) {
181 os << boost::any_cast<int>(any);
183 if(type() ==
typeid(double)) {
184 os << boost::any_cast<double>(any);
186 if(type() ==
typeid(std::string)) {
187 os << boost::any_cast<std::string>(any);
194 std::ostream & operator<<(std::ostream & os, poly_type
const & arg) {
199 #define FSC_POLY_TYPE_OP_SUPPORT(OP) \
200 poly_type operator OP(poly_type const & a, poly_type const & b) { \
205 template<typename T> \
206 poly_type operator OP(poly_type const & p, T const & t) { \
207 return p OP poly_type(t); \
209 template<typename T> \
210 poly_type operator OP(T const & t, poly_type const & p) { \
211 return poly_type(t) OP p; \
215 #define FSC_POLY_TYPE_OPEQ_SUPPORT(OP, TYPE) \
216 TYPE & operator OP(TYPE & a, fsc::poly_type const & b) { \
221 FSC_POLY_TYPE_OP_SUPPORT(+)
222 FSC_POLY_TYPE_OP_SUPPORT(-)
223 FSC_POLY_TYPE_OP_SUPPORT(/)
224 FSC_POLY_TYPE_OP_SUPPORT(*)
225 FSC_POLY_TYPE_OPEQ_SUPPORT(+=, std::
string)
226 FSC_POLY_TYPE_OPEQ_SUPPORT(+=,
double)
227 FSC_POLY_TYPE_OPEQ_SUPPORT(-=,
double)
228 FSC_POLY_TYPE_OPEQ_SUPPORT(*=,
double)
229 FSC_POLY_TYPE_OPEQ_SUPPORT(/=,
double)
230 FSC_POLY_TYPE_OPEQ_SUPPORT(+=,
int)
231 FSC_POLY_TYPE_OPEQ_SUPPORT(-=,
int)
232 FSC_POLY_TYPE_OPEQ_SUPPORT(*=,
int)
233 FSC_POLY_TYPE_OPEQ_SUPPORT(/=,
int)
235 #undef FSC_POLY_TYPE_OP_SUPPORT
236 #undef FSC_POLY_TYPE_OPEQ_SUPPORT
280 #endif //FSC_POLY_TYPE_HEADER