libmoost
/home/mhx/git/github/libmoost/include/moost/configurable/binding.hpp
Go to the documentation of this file.
00001 /* vim:set ts=3 sw=3 sts=3 et: */
00028 #ifndef MOOST_CONFIGURABLE_BINDING_HPP__
00029 #define MOOST_CONFIGURABLE_BINDING_HPP__
00030 
00031 #include <stdexcept>
00032 #include <string>
00033 
00034 #include "persistable.h"
00035 
00036 namespace moost { namespace configurable {
00037 
00039 template<typename T>
00040 class binding : public persistable
00041 {
00042 private:
00043   T &         m_value;
00044   const bool  m_has_default_value;
00045   const T     m_default_value;
00046 
00047 public:
00048   binding(T & value)
00049   : m_value(value),
00050     m_has_default_value(false),
00051     m_default_value(T()) {}
00052 
00053   binding(T & value, const T & default_value)
00054   : m_value(value),
00055     m_has_default_value(true),
00056     m_default_value(default_value) {}
00057 
00058   void read(std::istream & source)
00059   {
00060     source >> m_value;
00061     if (source.fail())
00062       throw std::runtime_error("cannot interpret value");
00063   }
00064   void write(std::ostream & dest, int /* indent */ = 0) const { dest << m_value; }
00065   void set_default()
00066   {
00067     if (!m_has_default_value)
00068       throw std::runtime_error("must set binding (no default value)");
00069     m_value = m_default_value;
00070   }
00071 };
00072 
00074 template<>
00075 class binding<std::string> : public persistable
00076 {
00077 private:
00078   std::string &     m_value;
00079   const bool        m_has_default_value;
00080   const std::string m_default_value;
00081 
00082 public:
00083   binding(std::string & value)
00084   : m_value(value),
00085     m_has_default_value(false),
00086     m_default_value("") {}
00087 
00088   binding(std::string & value, const std::string & default_value)
00089   : m_value(value),
00090     m_has_default_value(true),
00091     m_default_value(default_value) {}
00092 
00093   // TODO: escape newlines
00094   void read(std::istream & source) { std::getline(source, m_value); }
00095   void write(std::ostream & dest, int /* indent */ = 0) const { dest << m_value; }
00096   void set_default()
00097   {
00098     if (!m_has_default_value)
00099       throw std::runtime_error("must set binding (no default value)");
00100     m_value = m_default_value;
00101   }
00102 };
00103 
00105 template<>
00106 class binding<bool> : public persistable
00107 {
00108 private:
00109   bool &     m_value;
00110   const bool        m_has_default_value;
00111   const bool m_default_value;
00112 
00113 public:
00114   binding(bool & value)
00115   : m_value(value),
00116     m_has_default_value(false),
00117     m_default_value("") {}
00118 
00119   binding(bool & value, const bool & default_value)
00120   : m_value(value),
00121     m_has_default_value(true),
00122     m_default_value(default_value) {}
00123 
00124   void read(std::istream & source)
00125   {
00126     std::string token;
00127     source >> token;
00128     if (token == "true" || token == "True" || token == "TRUE" || token == "1")
00129       m_value = true;
00130     else if (token == "false" || token == "False" || token == "FALSE" || token == "0")
00131       m_value = false;
00132     else
00133       throw std::runtime_error("cannot interpret value");
00134   }
00135   void write(std::ostream & dest, int /* indent */ = 0) const { dest << (m_value ? "true" : "false"); }
00136   void set_default()
00137   {
00138     if (!m_has_default_value)
00139       throw std::runtime_error("must set binding (no default value)");
00140     m_value = m_default_value;
00141   }
00142 };
00143 
00144 }} // moost::configurable
00145 
00146 #endif // MOOST_CONFIGURABLE_BINDING_HPP__