summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrandomdan <randomdan@localhost>2012-12-09 15:26:05 +0000
committerrandomdan <randomdan@localhost>2012-12-09 15:26:05 +0000
commit88480a4fb234fb4f31475a9c2b0b1b1ab723254f (patch)
tree28a1b007957b838b4fb43d689f0901f4d455c204
parentKeep the same DB connection throughout the bulk load process (diff)
downloadproject2-88480a4fb234fb4f31475a9c2b0b1b1ab723254f.tar.bz2
project2-88480a4fb234fb4f31475a9c2b0b1b1ab723254f.tar.xz
project2-88480a4fb234fb4f31475a9c2b0b1b1ab723254f.zip
Support default values of different type to target values in options
Support direct assignment of values to targets without lexical casts
-rw-r--r--project2/common/options.h38
1 files changed, 34 insertions, 4 deletions
diff --git a/project2/common/options.h b/project2/common/options.h
index b4cbaf8..2ccb7ec 100644
--- a/project2/common/options.h
+++ b/project2/common/options.h
@@ -7,6 +7,27 @@
#include <list>
#include <boost/lexical_cast.hpp>
+namespace std {
+ //
+ // Should be part of the standard headers, but seems to be missing
+ //
+ template<typename _Tp, typename _Up>
+ class __is_assignable_helper : public __sfinae_types {
+ template<typename _Tp1, typename _Up1>
+ static decltype(declval<_Tp1>() = declval<_Up1>(), __one()) __test(int);
+
+ template<typename, typename>
+ static __two __test(...);
+
+ public:
+ static constexpr bool value = sizeof(__test<_Tp, _Up>(0)) == 1;
+ };
+ /// is_assignable
+ template<typename _Tp, typename _Up>
+ struct is_assignable : public integral_constant<bool, __is_assignable_helper<_Tp, _Up>::value>
+ { };
+}
+
class Options {
public:
class Target;
@@ -43,10 +64,19 @@ class Options {
*target = T();
}
void assign(const Glib::ustring & value) const {
- *target = boost::lexical_cast<T>(value);
+ doAssign(value);
}
protected:
T * target;
+ private:
+ template <typename dummy = int>
+ void doAssign(const Glib::ustring & value, typename boost::disable_if<std::is_assignable<T, Glib::ustring>, dummy>::type = 0) const {
+ *target = boost::lexical_cast<T>(value);
+ }
+ template <typename dummy = int>
+ void doAssign(const Glib::ustring & value, typename boost::enable_if<std::is_assignable<T, Glib::ustring>, dummy>::type = 0) const {
+ *target = value;
+ }
};
template <typename T> class TypedTarget<std::vector<T> > : public InstanceTarget {
@@ -66,9 +96,9 @@ class Options {
VofT * target;
};
- template <typename T> class DefaultTypedTarget : public TypedTarget<T> {
+ template <typename T, typename D> class DefaultTypedTarget : public TypedTarget<T> {
public:
- DefaultTypedTarget(T * t, const T & d) :
+ DefaultTypedTarget(T * t, const D & d) :
TypedTarget<T>(t),
defValue(d) {
}
@@ -104,7 +134,7 @@ class Options {
template <typename T, typename D>
static
TargetPtr value(T * t, const D & d) {
- return new DefaultTypedTarget<T>(t, d);
+ return new DefaultTypedTarget<T, D>(t, d);
}
void reset() const;