Parametrizable.cpp
Go to the documentation of this file.
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 #include "Parametrizable.h"
00037 #include <boost/format.hpp>
00038 
00039 namespace PointMatcherSupport
00040 {
00041     using namespace std;
00042     
00044     Parametrizable::InvalidParameter::InvalidParameter(const std::string& reason):
00045         runtime_error(reason)
00046     {}
00047     
00049     std::ostream& operator<< (std::ostream& o, const Parametrizable::ParameterDoc& p)
00050     {
00051         o << p.name << " (default: " << p.defaultValue << ") - " << p.doc;
00052         if (!p.minValue.empty())
00053             o << " - min: " << p.minValue;
00054         if (!p.maxValue.empty())
00055             o << " - max: " << p.maxValue;
00056         return o;
00057     }
00058     
00060     std::ostream& operator<< (std::ostream& o, const Parametrizable::ParametersDoc& p)
00061     {
00062         for (auto it = p.cbegin(); it != p.cend(); ++it)
00063             o << "- " << *it << endl;
00064         return o;
00065     }
00066 
00068     bool FalseLexicalComparison(std::string, std::string)
00069     {
00070         return false;
00071     }
00072     
00073     /*template<typename S>
00074     bool ScalarLexicalComparison(std::string a, std::string b)
00075     {
00076         return boost::lexical_cast<S>(a) < boost::lexical_cast<S>(b);
00077     }
00078     
00079     Uncomment once most people have gcc >= 4.5
00080     Shame on bug  9050 (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=9050)
00081     template<typename S>
00082     Parametrizable::ParameterDoc::ParameterDoc(const std::string& name, const std::string& doc, const S defaultValue, const S minValue, const S maxValue):
00083         name(name),
00084         doc(doc),
00085         defaultValue(boost::lexical_cast<string>(defaultValue)), 
00086         minValue(boost::lexical_cast<string>(minValue)), 
00087         maxValue(boost::lexical_cast<string>(maxValue)),
00088         comp(ScalarLexicalComparison<S>)
00089     {}
00090     
00091     template<typename S>
00092     Parametrizable::ParameterDoc::ParameterDoc(const std::string& name, const std::string& doc, const S defaultValue):
00093         name(name),
00094         doc(doc),
00095         defaultValue(boost::lexical_cast<string>(defaultValue)), 
00096         minValue(""), 
00097         maxValue(""),
00098         comp(TrueLexicalComparison)
00099     {}
00100     */
00101     
00103     Parametrizable::ParameterDoc::ParameterDoc(const std::string& name, const std::string& doc, const std::string& defaultValue, const std::string& minValue, const std::string& maxValue, LexicalComparison comp):
00104         name(name),
00105         doc(doc),
00106         defaultValue(defaultValue), 
00107         minValue(minValue), 
00108         maxValue(maxValue),
00109         comp(comp)
00110     {}
00111     
00113     Parametrizable::ParameterDoc::ParameterDoc(const std::string& name, const std::string& doc, const std::string& defaultValue):
00114         name(name),
00115         doc(doc),
00116         defaultValue(boost::lexical_cast<string>(defaultValue)), 
00117         minValue(""), 
00118         maxValue(""),
00119         comp(FalseLexicalComparison)
00120     {}
00121     
00123     Parametrizable::ParametersDoc::ParametersDoc(std::initializer_list<ParameterDoc> list):
00124         std::vector<ParameterDoc>(list)
00125     {}
00126     
00128     Parametrizable::ParametersDoc::ParametersDoc()
00129     {}
00130     
00131     /*
00132     Again, not used because fo gcc bug 9050
00133     
00134     template<typename S>
00135     Parametrizable::Parameter::Parameter(const S value):
00136         std::string(boost::lexical_cast<string>(value))
00137     {}
00138     
00139     // force instantiation of constructors
00140     template Parametrizable::ParameterDoc::ParameterDoc<int>(const std::string, const std::string, const int);
00141     template Parametrizable::ParameterDoc::ParameterDoc<float>(const std::string, const std::string, const float);
00142     template Parametrizable::ParameterDoc::ParameterDoc<double>(const std::string, const std::string, const double);
00143     template Parametrizable::ParameterDoc::ParameterDoc<bool>(const std::string, const std::string, const bool);
00144     template Parametrizable::ParameterDoc::ParameterDoc<std::string>(const std::string, const std::string, const std::string);
00145     template Parametrizable::ParameterDoc::ParameterDoc<const char*>(const std::string, const std::string, const char*);
00146     
00147     template Parametrizable::ParameterDoc::ParameterDoc<int>(const std::string, const std::string, const int, const int, const int);
00148     template Parametrizable::ParameterDoc::ParameterDoc<float>(const std::string, const std::string, const float, const float, const float);
00149     template Parametrizable::ParameterDoc::ParameterDoc<double>(const std::string, const std::string, const double, const double, const double);
00150     
00151     template Parametrizable::Parameter::Parameter<int>(const int);
00152     template Parametrizable::Parameter::Parameter<float>(const float);
00153     template Parametrizable::Parameter::Parameter<double>(const double);
00154     template Parametrizable::Parameter::Parameter<bool>(const bool);
00155     template Parametrizable::Parameter::Parameter<std::string>(const std::string);
00156 
00157     */
00158     
00160     Parametrizable::Parametrizable():
00161         className("unknown")
00162     {}
00163     
00165     Parametrizable::Parametrizable(
00166         const std::string& className, const ParametersDoc paramsDoc, const Parameters& params):
00167         className(className),
00168         parametersDoc(paramsDoc)
00169     {
00170         // fill current parameters from either values passed as argument, or default value
00171         for (auto it = parametersDoc.cbegin(); it != parametersDoc.cend(); ++it)
00172         {
00173             const string& paramName(it->name);
00174             Parameters::const_iterator paramIt(params.find(paramName));
00175             if (paramIt != params.end())
00176             {
00177                 const string& val(paramIt->second);
00178                 if (it->comp(val, it->minValue))
00179                     throw InvalidParameter((boost::format("Value %1% of parameter %2% in class %3% is smaller than minimum admissible value %4%") % val % paramName % className % it->minValue).str());
00180                 if (it->comp(it->maxValue, val))
00181                     throw InvalidParameter((boost::format("Value %1% of parameter %2% in class %3% is larger than maximum admissible value %4%") % val % paramName % className % it->maxValue).str());
00182                 parameters[paramName] = val;
00183             }
00184             else
00185                 parameters[paramName] = it->defaultValue;
00186         }
00187     }
00188     
00190     Parametrizable::~Parametrizable()
00191     {}
00192 
00194     std::string Parametrizable::getParamValueString(const std::string& paramName)
00195     {
00196         Parameters::const_iterator paramIt(parameters.find(paramName));
00197         if (paramIt == parameters.end())
00198             throw InvalidParameter((boost::format("Parameter %1% does not exist in class %2%") % paramName % className).str());
00199         // TODO: use string distance to propose close one, copy/paste code from Aseba
00200         this->parametersUsed.insert(paramIt->first);
00201         return paramIt->second;
00202     }
00203 } // namespace PointMatcherSupport


libpointmatcher
Author(s): Stéphane Magnenat, François Pomerleau
autogenerated on Thu Jan 2 2014 11:16:06