00001 #ifndef DVUTIL_CONVERT_H
00002 #define DVUTIL_CONVERT_H
00003
00004 #include <stdexcept>
00005 #include <sstream>
00006 #include <typeinfo>
00007
00008 #include <dvutil/trace.h>
00009
00010 namespace Dv {
00011
00012 template<typename Target, typename Source>
00013 struct Convert {
00014 bool
00015 operator()(Target& target, const Source& source) {
00016 std::ostringstream oss;
00017 if (! (oss << source) )
00018 return false;
00019 std::istringstream iss(oss.str());
00020 if (! (iss >> target) )
00021 return false;
00022 return true;
00023 }
00024 };
00025
00026
00027 template<typename T>
00028 struct Convert<T,T> {
00029 bool
00030 operator()(T& target, const T& source) {
00031 if (&target != &source)
00032 target = source;
00033 return true;
00034 }
00035 };
00036
00037
00038 template<>
00039 struct Convert<std::string, std::string> {
00040 bool
00041 operator()(std::string& target, const std::string& source) {
00042 if (&target != &source)
00043 target = source;
00044 return true;
00045 }
00046 };
00047
00048 template<>
00049 struct Convert<std::string, const char*> {
00050 bool
00051 operator()(std::string& target, const char* source) {
00052 target.assign(source);
00053 return true;
00054 }
00055 };
00056
00057 template<typename Target>
00058 struct Convert<Target, std::string> {
00059 bool
00060 operator()(Target& target, const std::string& source) {
00061 std::istringstream iss(source);
00062 return (iss >> target);
00063 }
00064 };
00065
00066 template<typename Source>
00067 struct Convert<std::string, Source> {
00068 bool
00069 operator()(std::string& target, const Source& source) {
00070 std::ostringstream oss;
00071 if (! (oss << source) )
00072 return false;
00073 target = oss.str();
00074 return true;
00075 }
00076 };
00077
00078 template<typename Target, typename Source>
00079 bool
00080 convert(Target& target, const Source& source) {
00081 return Convert<Target,Source>()(target, source);
00082 }
00083
00084 template<typename Target, typename Source>
00085 Target
00086 convert(const Source& source, const Target& default_value) {
00087 Target target;
00088 if (convert(target,source))
00089 return target;
00090 else
00091 return default_value;
00092 }
00093
00094 template<typename Source>
00095 std::string
00096 tostring(const Source& source, const std::string& default_value = "") {
00097 std::string target;
00098 if (convert(target,source))
00099 return target;
00100 else
00101 return default_value;
00102 }
00103
00104 template<typename Target>
00105 Target
00106 fromstring(const std::string& source, const Target& default_value) {
00107 Target target;
00108 if (convert(target,source))
00109 return target;
00110 else
00111 return default_value;
00112 }
00113
00114 template<typename Target>
00115 Target
00116 fromstring(const std::string& source) {
00117 Target target;
00118 if (convert(target,source))
00119 return target;
00120 throw std::domain_error("Dv::fromstring(const std::string&): cannot convert '" + source + "' to " + typeid(Target).name());
00121 }
00122
00123 }
00124 #endif