libpointmatcher  1.1.0
Parametrizable.h
00001 // kate: replace-tabs off; indent-width 4; indent-mode normal
00002 // vim: ts=4:sw=4:noexpandtab
00003 /*
00004 
00005 Copyright (c) 2010--2012,
00006 François Pomerleau and Stephane Magnenat, ASL, ETHZ, Switzerland
00007 You can contact the authors at <f dot pomerleau at gmail dot com> and
00008 <stephane at magnenat dot net>
00009 
00010 All rights reserved.
00011 
00012 Redistribution and use in source and binary forms, with or without
00013 modification, are permitted provided that the following conditions are met:
00014     * Redistributions of source code must retain the above copyright
00015       notice, this list of conditions and the following disclaimer.
00016     * Redistributions in binary form must reproduce the above copyright
00017       notice, this list of conditions and the following disclaimer in the
00018       documentation and/or other materials provided with the distribution.
00019     * Neither the name of the <organization> nor the
00020       names of its contributors may be used to endorse or promote products
00021       derived from this software without specific prior written permission.
00022 
00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00024 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00025 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00026 DISCLAIMED. IN NO EVENT SHALL ETH-ASL BE LIABLE FOR ANY
00027 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00028 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00029 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00030 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00031 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00032 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033 
00034 */
00035 
00036 #ifndef __POINTMATCHER_PARAMETRIZABLE_H
00037 #define __POINTMATCHER_PARAMETRIZABLE_H
00038 
00039 #include <stdexcept>
00040 #include <vector>
00041 #include <map>
00042 #include <set>
00043 #include <string>
00044 #include <boost/lexical_cast.hpp>
00045 #include <limits>
00046 #define BOOST_ASSIGN_MAX_PARAMS 6
00047 #include <boost/assign/list_of.hpp>
00048 #include <boost/assign/list_inserter.hpp>
00049 
00050 
00051 namespace PointMatcherSupport
00052 {   
00054     template<typename Target>
00055     inline Target lexical_cast_scalar_to_string(const std::string& arg)
00056     {
00057         if (arg == "inf")
00058             return std::numeric_limits<Target>::infinity();
00059         else if (arg == "-inf")
00060             return -std::numeric_limits<Target>::infinity();
00061         else if (arg == "nan")
00062             return std::numeric_limits<Target>::quiet_NaN();
00063         else
00064             return boost::lexical_cast<Target>(arg);
00065     }
00066     
00068     template<typename Target, typename Source>
00069     inline Target lexical_cast(const Source& arg)
00070     {
00071         return boost::lexical_cast<Target>(arg);
00072     }
00073     
00075     template<>
00076     inline float lexical_cast(const std::string& arg) { return lexical_cast_scalar_to_string<float>(arg); }
00078     template<>
00079     inline double lexical_cast(const std::string& arg) { return lexical_cast_scalar_to_string<double>(arg); }
00080     
00081     //
00082     
00084     template<typename S>
00085     std::string toParam(const S& value)
00086     {
00087         return lexical_cast<std::string>(value);
00088     }
00089     
00091     struct Parametrizable
00092     {
00094         struct InvalidParameter: std::runtime_error
00095         {
00096             InvalidParameter(const std::string& reason);
00097         };
00098         
00100         typedef bool(*LexicalComparison)(std::string a, std::string b);
00101         
00103         template<typename S>
00104         static bool Comp(std::string a, std::string b)
00105         {
00106             return lexical_cast<S>(a) < lexical_cast<S>(b);
00107         }
00108         
00110         struct ParameterDoc
00111         {
00112             std::string name; 
00113             std::string doc; 
00114             std::string defaultValue; 
00115             std::string minValue; 
00116             std::string maxValue; 
00117             LexicalComparison comp; 
00118             
00119             /*
00120             This code is beautiful, this code is correct, this code does not work ;-(
00121             Blame gcc bug 9050 (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=9050), shame
00122             on them forever and beyond. People being laaaazzzy adopters, I'm forced to use
00123             something that works on gcc 4.4.
00124             
00125             template<typename S>
00126             ParameterDoc(const std::string& name, const std::string& doc, const S defaultValue, const S minValue, const S maxValue = std::numeric_limits<S>::max());
00127             template<typename S>
00128             ParameterDoc(const std::string& name, const std::string& doc, const S defaultValue);
00129             */
00130             ParameterDoc(const std::string& name, const std::string& doc, const std::string& defaultValue, const std::string& minValue, const std::string& maxValue, LexicalComparison comp);
00131             ParameterDoc(const std::string& name, const std::string& doc, const std::string& defaultValue);
00132             
00133             friend std::ostream& operator<< (std::ostream& o, const ParameterDoc& p);
00134         };
00135         
00137         typedef std::vector<ParameterDoc> ParametersDoc;
00138         
00139         /*
00140         Again, not used because fo gcc bug 9050
00141         struct Parameter: public std::string
00142         {
00143             template<typename S>
00144             Parameter(const S value);
00145             Parameter(){}
00146         };
00147         */
00148         typedef std::string Parameter; 
00149         typedef std::map<std::string, Parameter> Parameters; 
00150         typedef std::set<std::string> ParametersUsed; 
00151         
00152         const std::string className; 
00153         const ParametersDoc parametersDoc; 
00154         Parameters parameters; 
00155         ParametersUsed parametersUsed; 
00156         
00157         Parametrizable();
00158         Parametrizable(const std::string& className, const ParametersDoc paramsDoc, const Parameters& params);
00159         virtual ~Parametrizable();
00160         
00161         std::string getParamValueString(const std::string& paramName);
00162         
00164         template<typename S>
00165         S get(const std::string& paramName) { return lexical_cast<S>(getParamValueString(paramName)); }
00166         
00167         friend std::ostream& operator<< (std::ostream& o, const Parametrizable& p);
00168     };
00169     std::ostream& operator<< (std::ostream& o, const Parametrizable::ParametersDoc& p);
00170 } // namespace PointMatcherSupport
00171 
00172 #endif // __POINTMATCHER_PARAMETRIZABLE_H