vars_internal.h
Go to the documentation of this file.
00001 /* This file is part of the Pangolin Project.
00002  * http://github.com/stevenlovegrove/Pangolin
00003  *
00004  * Copyright (c) 2011 Steven Lovegrove
00005  *
00006  * Permission is hereby granted, free of charge, to any person
00007  * obtaining a copy of this software and associated documentation
00008  * files (the "Software"), to deal in the Software without
00009  * restriction, including without limitation the rights to use,
00010  * copy, modify, merge, publish, distribute, sublicense, and/or sell
00011  * copies of the Software, and to permit persons to whom the
00012  * Software is furnished to do so, subject to the following
00013  * conditions:
00014  *
00015  * The above copyright notice and this permission notice shall be
00016  * included in all copies or substantial portions of the Software.
00017  *
00018  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00019  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
00020  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00021  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
00022  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
00023  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00024  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
00025  * OTHER DEALINGS IN THE SOFTWARE.
00026  */
00027 
00028 #ifndef PANGOLIN_VARS_INTERNAL_H
00029 #define PANGOLIN_VARS_INTERNAL_H
00030 
00031 #include <boost/utility.hpp>
00032 #include <boost/type_traits.hpp>
00033 //#include <boost/lexical_cast.hpp>
00034 #include <iostream>
00035 
00036 
00037 namespace pangolin
00038 {
00039 
00040 struct BadInputException : std::exception
00041 {
00042     char const* what() const throw()
00043     {
00044         return "Failed to serialise type";
00045     }
00046 };
00047 
00048 // Generic conversion through serialisation from / to string
00049 template<typename T, typename S> struct Convert
00050 {
00051     static T Do(const S& src)
00052     {
00053         std::ostringstream oss;
00054         oss << src;
00055         std::istringstream iss(oss.str());
00056         T target;
00057         iss >> target;
00058 
00059         if(iss.fail())
00060             throw BadInputException();
00061 
00062         return target;
00063         //    return boost::lexical_cast<T>(src);
00064     }
00065 };
00066 
00067 // Apply bool alpha IO manipulator for bool types
00068 template<> struct Convert<bool,std::string>
00069 {
00070     static bool Do(const std::string& src)
00071     {
00072         bool target;
00073         std::istringstream iss(src);
00074         iss >> target;
00075 
00076         if(iss.fail())
00077         {
00078             std::istringstream iss2(src);
00079             iss2 >> std::boolalpha >> target;
00080             if( iss2.fail())
00081                 throw BadInputException();
00082         }
00083 
00084         return target;
00085     }
00086 };
00087 
00088 // From strings
00089 template<typename T> struct Convert<T,std::string>
00090 {
00091     static T Do(const std::string& src)
00092     {
00093         T target;
00094         std::istringstream iss(src);
00095         iss >> target;
00096 
00097         if(iss.fail())
00098             throw BadInputException();
00099 
00100         return target;
00101     }
00102 };
00103 
00104 // To strings
00105 template<typename S> struct Convert<std::string, S>
00106 {
00107     static std::string Do(const S& src)
00108     {
00109         std::ostringstream oss;
00110         oss << src;
00111         return oss.str();
00112     }
00113 };
00114 
00115 // Between strings is just a copy
00116 template<> struct Convert<std::string, std::string>
00117 {
00118     static std::string Do(const std::string& src)
00119     {
00120         return src;
00121     }
00122 };
00123 
00124 struct UnknownTypeException : std::exception
00125 {
00126     char const* what() const throw()
00127     {
00128         return "Unknown type in generic container";
00129     }
00130 };
00131 
00132 struct _Var
00133 {
00134     _Var()
00135         : val(NULL), val_default(NULL), generic(false)
00136     {}
00137     ~_Var()
00138     {
00139         clean();
00140     }
00141 
00142     void create(void* new_val, void* new_val_default, const char* new_type_name)
00143     {
00144         clean();
00145         val = new_val;
00146         val_default = new_val_default;
00147         type_name = new_type_name;
00148         generic = false;
00149     }
00150 
00151     void clean()
00152     {
00153         if (val!=NULL)
00154         {
00155             if( type_name == typeid(double).name() )
00156             {
00157                 delete (double *) val;
00158             }
00159             else if( type_name == typeid(int).name() )
00160             {
00161                 delete (int *) val;
00162             }
00163             else if( type_name == typeid(std::string).name() )
00164             {
00165                 delete (std::string *) val;
00166             }
00167             else if( type_name == typeid(bool).name() )
00168             {
00169                 delete (bool *) val;
00170             }
00171             else
00172             {
00173                 throw UnknownTypeException();
00174             }
00175         }
00176 
00177         if (val_default!=NULL)
00178         {
00179             if( type_name == typeid(double).name() )
00180             {
00181                 delete (double *) val_default;
00182             }
00183             else if( type_name == typeid(int).name() )
00184             {
00185                 delete (int *) val_default;
00186             }
00187             else if( type_name == typeid(std::string).name() )
00188             {
00189                 delete (std::string *) val_default;
00190             }
00191             else if( type_name == typeid(bool).name() )
00192             {
00193                 delete (bool *) val_default;
00194             }
00195             else
00196             {
00197                 throw UnknownTypeException();
00198             }
00199         }
00200     }
00201 
00202 
00203 
00204 
00205     void* val;
00206     void* val_default;
00207 
00208     const char* type_name;
00209 
00210     bool generic;
00211     std::string meta_full_name;
00212     std::string meta_friendly;
00213     double meta_range[2];
00214     double meta_increment;
00215     int meta_flags;
00216     bool meta_gui_changed;
00217     bool logscale;
00218 };
00219 
00220 // Forward declaration
00221 template<typename T, typename S, class Enable1 = void, class Enable2 = void, class Enable3 = void>
00222 struct _Accessor;
00223 
00224 template<typename T>
00225 struct Accessor
00226 {
00227     virtual ~Accessor() {}
00228     virtual const T& Get() const = 0;
00229     virtual void Set(const T& val) = 0;
00230     static Accessor<T>* Create(const char* typeidname, void* var)
00231     {
00232         if( typeidname == typeid(double).name() )
00233         {
00234             return new _Accessor<T,double>( *(double*)var);
00235         }
00236         else if( typeidname == typeid(int).name() )
00237         {
00238             return new _Accessor<T,int>( *(int*)var );
00239         }
00240         else if( typeidname == typeid(std::string).name() )
00241         {
00242             return new _Accessor<T,std::string>( *(std::string*)var );
00243         }
00244         else if( typeidname == typeid(bool).name() )
00245         {
00246             return new _Accessor<T,bool>( *(bool*)var );
00247         }
00248         else
00249         {
00250             throw UnknownTypeException();
00251         }
00252     }
00253 };
00254 
00255 template<typename T, typename S>
00256 struct _Accessor<T,S, typename boost::enable_if_c<
00257 (boost::is_scalar<T>::value || boost::is_same<T,bool>::value) &&
00258 (boost::is_scalar<S>::value || boost::is_same<S,bool>::value) &&
00259 !boost::is_same<T,S>::value
00260 >::type> : Accessor<T>
00261 {
00262     _Accessor(S& var) : var(var)
00263 {
00264     //    std::cout << "scalar" << std::endl;
00265 }
00266 
00267 const T& Get() const
00268 {
00269     cache = (T)var;
00270     return cache;
00271 }
00272 
00273 void Set(const T& val)
00274 {
00275     var = (S)val;
00276 }
00277 
00278 S& var;
00279 mutable T cache;
00280 };
00281 
00282 template<typename T>
00283 struct _Accessor<T,T> : Accessor<T>
00284 {
00285     _Accessor(T& var) : var(var)
00286     {
00287         //    std::cout << "same" << std::endl;
00288     }
00289 
00290     const T& Get() const
00291     {
00292         return var;
00293     }
00294 
00295     void Set(const T& val)
00296     {
00297         var = val;
00298     }
00299     T& var;
00300 };
00301 
00302 template<typename T, typename S>
00303 struct _Accessor<T,S ,typename boost::enable_if_c<
00304 !((boost::is_scalar<T>::value || boost::is_same<T,bool>::value) &&
00305   (boost::is_scalar<S>::value || boost::is_same<S,bool>::value)) &&
00306 !boost::is_same<T,S>::value
00307 >::type> : Accessor<T>
00308 {
00309     _Accessor(S& var) : var(var)
00310 {
00311 }
00312 
00313 const T& Get() const
00314 {
00315     //    try{
00316     cache = Convert<T,S>::Do(var);
00317     //    }catch(BadInputException e) {
00318     //        std::cerr << e.what() << std::endl;
00319     //    }
00320 
00321     return cache;
00322 }
00323 
00324 void Set(const T& val)
00325 {
00326     //    try{
00327     var = Convert<S,T>::Do(val);
00328     //    }catch(BadInputException e) {
00329     //      std::cerr << "Unable to convert: " << e.what() << std::endl;
00330     //    }
00331 }
00332 S& var;
00333 mutable T cache;
00334 };
00335 
00336 }
00337 
00338 #endif // PANGOLIN_VARS_INTERNAL_H
00339 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines


pangolin_wrapper
Author(s): Todor Stoyanov
autogenerated on Wed Feb 13 2013 14:03:25