ompl/base/GenericParam.h
00001 /*********************************************************************
00002 * Software License Agreement (BSD License)
00003 *
00004 *  Copyright (c) 2011, Willow Garage
00005 *  All rights reserved.
00006 *
00007 *  Redistribution and use in source and binary forms, with or without
00008 *  modification, are permitted provided that the following conditions
00009 *  are met:
00010 *
00011 *   * Redistributions of source code must retain the above copyright
00012 *     notice, this list of conditions and the following disclaimer.
00013 *   * Redistributions in binary form must reproduce the above
00014 *     copyright notice, this list of conditions and the following
00015 *     disclaimer in the documentation and/or other materials provided
00016 *     with the distribution.
00017 *   * Neither the name of the Willow Garage nor the names of its
00018 *     contributors may be used to endorse or promote products derived
00019 *     from this software without specific prior written permission.
00020 *
00021 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032 *  POSSIBILITY OF SUCH DAMAGE.
00033 *********************************************************************/
00034 
00035 /* Author: Ioan Sucan */
00036 
00037 #ifndef OMPL_BASE_GENERIC_PARAM_
00038 #define OMPL_BASE_GENERIC_PARAM_
00039 
00040 #include "ompl/util/Console.h"
00041 #include "ompl/util/ClassForward.h"
00042 #include <boost/function.hpp>
00043 #include <boost/lexical_cast.hpp>
00044 #include <boost/type_traits.hpp>
00045 #include <iostream>
00046 #include <string>
00047 #include <vector>
00048 #include <map>
00049 
00050 namespace ompl
00051 {
00052     namespace base
00053     {
00054 
00056 
00057         OMPL_CLASS_FORWARD(GenericParam);
00059 
00065         class GenericParam
00066         {
00067         public:
00068 
00070             GenericParam(const std::string &name) : name_(name)
00071             {
00072             }
00073 
00074             virtual ~GenericParam()
00075             {
00076             }
00077 
00079             const std::string& getName() const
00080             {
00081                 return name_;
00082             }
00083 
00085             void setName(const std::string &name)
00086             {
00087                 name_ = name;
00088             }
00089 
00091             virtual bool setValue(const std::string &value) = 0;
00092 
00094             virtual std::string getValue() const = 0;
00095 
00097             template<typename T>
00098             GenericParam& operator=(const T &value)
00099             {
00100                 try
00101                 {
00102                     setValue(boost::lexical_cast<std::string>(value));
00103                 }
00104                 catch (boost::bad_lexical_cast &e)
00105                 {
00106                     OMPL_WARN("Invalid value format specified for parameter '%s': %s", name_.c_str(), e.what());
00107                 }
00108                 return *this;
00109             }
00110 
00112             void setRangeSuggestion(const std::string &rangeSuggestion)
00113             {
00114                 rangeSuggestion_ = rangeSuggestion;
00115             }
00116 
00118             const std::string& getRangeSuggestion() const
00119             {
00120                 return rangeSuggestion_;
00121             }
00122 
00123         protected:
00124 
00127             template<typename T>
00128             const std::string& maybeWrapBool(const std::string &value) const
00129             {
00130                 return boost::is_same<T, bool>::value ? truthValueTo01Str(value) : value;
00131             }
00132 
00134             std::string name_;
00135 
00149             std::string rangeSuggestion_;
00150 
00151          private:
00153             static const std::string& truthValueTo01Str(const std::string &value);
00154         };
00155 
00156 
00158         template<typename T>
00159         class SpecificParam : public GenericParam
00160         {
00161         public:
00162 
00164             typedef boost::function<void(T)> SetterFn;
00165 
00167             typedef boost::function<T()>     GetterFn;
00168 
00171             SpecificParam(const std::string &name, const SetterFn &setter, const GetterFn &getter = GetterFn()) :
00172                 GenericParam(name), setter_(setter), getter_(getter)
00173             {
00174                 if (!setter_ && !getter_)
00175                     OMPL_ERROR("At least one setter or getter function must be specified for parameter");
00176             }
00177 
00178             virtual ~SpecificParam()
00179             {
00180             }
00181 
00182             virtual bool setValue(const std::string &value)
00183             {
00184                 bool result = true;
00185                 try
00186                 {
00187                     if (setter_)
00188                         setter_(boost::lexical_cast<T>(GenericParam::maybeWrapBool<T>(value)));
00189                 }
00190                 catch (boost::bad_lexical_cast &e)
00191                 {
00192                     result = false;
00193                     OMPL_WARN("Invalid value format specified for parameter '%s': %s", name_.c_str(), e.what());
00194                 }
00195 
00196                 if (getter_)
00197                     OMPL_DEBUG("The value of parameter '%s' is now: '%s'", name_.c_str(), getValue().c_str());
00198                 else
00199                     OMPL_DEBUG("The value of parameter '%s' was set to: '%s'", name_.c_str(), value.c_str());
00200                 return result;
00201             }
00202 
00203             virtual std::string getValue() const
00204             {
00205                 if (getter_)
00206                     try
00207                     {
00208                         return boost::lexical_cast<std::string>(getter_());
00209                     }
00210                     catch (boost::bad_lexical_cast &e)
00211                     {
00212                         OMPL_WARN("Unable to parameter '%s' to string: %s", name_.c_str(), e.what());
00213                         return "";
00214                     }
00215                 else
00216                     return "";
00217             }
00218 
00219         protected:
00220 
00222             SetterFn setter_;
00223 
00225             GetterFn getter_;
00226         };
00227 
00229 
00230         OMPL_CLASS_FORWARD(ParamSet);
00232 
00234         class ParamSet
00235         {
00236         public:
00237 
00239             template<typename T>
00240             void declareParam(const std::string &name, const typename SpecificParam<T>::SetterFn &setter,
00241                               const typename SpecificParam<T>::GetterFn &getter = typename SpecificParam<T>::GetterFn())
00242             {
00243                 params_[name].reset(new SpecificParam<T>(name, setter, getter));
00244             }
00245 
00247             void add(const GenericParamPtr &param);
00248 
00250             void remove(const std::string &name);
00251 
00253             void include(const ParamSet &other, const std::string &prefix = "");
00254 
00268             bool setParam(const std::string &key, const std::string &value);
00269 
00271             bool getParam(const std::string &key, std::string &value) const;
00272 
00278             bool setParams(const std::map<std::string, std::string> &kv, bool ignoreUnknown = false);
00279 
00281             void getParams(std::map<std::string, std::string> &params) const;
00282 
00284             void getParamNames(std::vector<std::string> &params) const;
00285 
00287             void getParamValues(std::vector<std::string> &vals) const;
00288 
00290             const std::map<std::string, GenericParamPtr>& getParams() const;
00291 
00293             const GenericParamPtr& getParam(const std::string &key) const;
00294 
00296             bool hasParam(const std::string &key) const;
00297 
00299             GenericParam& operator[](const std::string &key);
00300 
00302             std::size_t size() const
00303             {
00304                 return params_.size();
00305             }
00306 
00308             void clear();
00309 
00311             void print(std::ostream &out) const;
00312 
00313         private:
00314 
00315             std::map<std::string, GenericParamPtr> params_;
00316         };
00317     }
00318 }
00319 
00320 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines