summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrandomdan <randomdan@localhost>2013-04-05 21:03:07 +0000
committerrandomdan <randomdan@localhost>2013-04-05 21:03:07 +0000
commit2524e8c47399136ba6fc504f9412aa985bae7941 (patch)
tree49b5eb6ecbdb0314fd833740a792ed26ce8c44dc
parentHack to workaround p2lib link issue (diff)
downloadproject2-2524e8c47399136ba6fc504f9412aa985bae7941.tar.bz2
project2-2524e8c47399136ba6fc504f9412aa985bae7941.tar.xz
project2-2524e8c47399136ba6fc504f9412aa985bae7941.zip
GCC 4.6 workaround for vector of objects with consts
Make options much more flexible with Boost function interface
-rw-r--r--project2/cgi/cgiContentNegotiate.cpp18
-rw-r--r--project2/cgi/cgiProgRouter.cpp11
-rw-r--r--project2/common/options.cpp25
-rw-r--r--project2/common/options.h138
-rw-r--r--project2/console/consoleEnvironment.cpp16
-rw-r--r--project2/json/couchSession.cpp4
6 files changed, 84 insertions, 128 deletions
diff --git a/project2/cgi/cgiContentNegotiate.cpp b/project2/cgi/cgiContentNegotiate.cpp
index 176441e..2ed54c9 100644
--- a/project2/cgi/cgiContentNegotiate.cpp
+++ b/project2/cgi/cgiContentNegotiate.cpp
@@ -10,11 +10,13 @@ class ContentNegotiateLoader : public PresenterLoader {
opts("Content negotiation options")
{
opts
- ("cgi.contentnegotiation.mappedtype", Options::value(&mappedTypes),
+ ("cgi.contentnegotiation.mappedtype", Options::functions(
+ [this](const VariableType & v) { mappedTypes.push_back(new MappedType(v)); },
+ boost::bind(&MappedTypes::clear, &mappedTypes)),
"mimetype=presenter list of types to negotiate")
;
}
-
+
const Options * options() const { return &opts; }
MultiRowSetPresenter * create(const ScriptNodePtr & s, const ObjectSource & os) const
@@ -25,16 +27,16 @@ class ContentNegotiateLoader : public PresenterLoader {
const auto mimetype = mimetypeAndWeight.substr(0, mimetypeAndWeight.find(';'));
if (mimetype == "*/*") break;
BOOST_FOREACH(const auto & t, mappedTypes) {
- if (t.Matches(mimetype)) {
- return PresenterLoader::getFor(t.present)->create(s, os);
+ if (t->Matches(mimetype)) {
+ return PresenterLoader::getFor(t->present)->create(s, os);
}
}
}
- return PresenterLoader::getFor(mappedTypes.begin()->present)->create(s, os);
+ return PresenterLoader::getFor((*mappedTypes.begin())->present)->create(s, os);
}
Options opts;
- class MappedType {
+ class MappedType : public IntrusivePtrBase {
public:
MappedType(const std::string & val) :
accept(val.substr(0, val.find('='))),
@@ -50,7 +52,9 @@ class ContentNegotiateLoader : public PresenterLoader {
const std::string accept;
const std::string present;
};
- std::vector<MappedType> mappedTypes;
+ typedef boost::intrusive_ptr<MappedType> MappedTypePtr;
+ typedef std::vector<MappedTypePtr> MappedTypes;
+ MappedTypes mappedTypes;
bool cacheable() const { return false; }
};
diff --git a/project2/cgi/cgiProgRouter.cpp b/project2/cgi/cgiProgRouter.cpp
index d094598..932242e 100644
--- a/project2/cgi/cgiProgRouter.cpp
+++ b/project2/cgi/cgiProgRouter.cpp
@@ -12,7 +12,7 @@ typedef std::map<std::string, std::string> VarMap;
class RoutingTable {
public:
- RoutingTable & operator=(const std::string & routeFile) {
+ void loadRoutesFromFile(const std::string & routeFile) {
routeScriptPath = routeFile;
if (routeFile.empty()) {
routes.clear();
@@ -21,7 +21,10 @@ class RoutingTable {
else {
setRouteScript();
}
- return *this;
+ }
+
+ void clearRoutes() {
+ routes.clear();
}
void onBefore()
@@ -128,7 +131,9 @@ class ProgRouterLoader : public RouterLoader::For<ProgRouter> {
opts("CGI Prog Router options")
{
opts
- ("cgi.progRouter.routes", Options::value(&routingTable),
+ ("cgi.progRouter.routes", Options::functions(
+ boost::bind(&RoutingTable::loadRoutesFromFile, &routingTable, _1),
+ boost::bind(&RoutingTable::clearRoutes, &routingTable)),
"Script file defining web service routes")
;
}
diff --git a/project2/common/options.cpp b/project2/common/options.cpp
index 13e189b..b2777fa 100644
--- a/project2/common/options.cpp
+++ b/project2/common/options.cpp
@@ -125,11 +125,19 @@ Options::find(const Glib::ustring & n) const {
return NULL;
}
-Options::InstanceTarget::InstanceTarget() :
- ts(Default)
+Options::InstanceTarget::InstanceTarget(const Assigner & a, const Resetter & r) :
+ ts(Default),
+ assigner(a),
+ resetter(r)
{
}
+bool
+Options::InstanceTarget::paramRequired() const
+{
+ return true;
+}
+
void
Options::InstanceTarget::consume(const Glib::ustring & p, const VariableType & v) const
{
@@ -143,3 +151,16 @@ Options::InstanceTarget::consume(const Glib::ustring & p, const VariableType & v
}
}
+void
+Options::InstanceTarget::reset() const
+{
+ ts = Default;
+ resetter();
+}
+
+void
+Options::InstanceTarget::assign(const VariableType & value) const
+{
+ assigner(value);
+}
+
diff --git a/project2/common/options.h b/project2/common/options.h
index 8b9e9a0..b336854 100644
--- a/project2/common/options.h
+++ b/project2/common/options.h
@@ -5,34 +5,11 @@
#include <intrusivePtrBase.h>
#include <vector>
#include <list>
-#include <boost/lexical_cast.hpp>
+#include <boost/bind.hpp>
+#include <boost/function.hpp>
#include <boost/utility/enable_if.hpp>
#include "variableType.h"
-#if !__GNUC_PREREQ(4,7)
-// If gcc_version >= 4.0
-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>
- { };
-}
-#endif
-
class Options {
public:
class Target;
@@ -45,83 +22,20 @@ class Options {
virtual void consume(const Glib::ustring & platform, const VariableType & value) const = 0;
};
typedef boost::intrusive_ptr<Target> TargetPtr;
+ typedef boost::function<void(const VariableType &)> Assigner;
+ typedef boost::function<void()> Resetter;
class InstanceTarget : public Target {
public:
- InstanceTarget();
- bool paramRequired() const {
- return true;
- }
+ InstanceTarget(const Assigner &, const Resetter &);
+ bool paramRequired() const;
void consume(const Glib::ustring & platform, const VariableType & value) const;
protected:
- virtual void assign(const VariableType & value) const = 0;
+ void reset() const;
+ void assign(const VariableType & value) const;
mutable TargetState ts;
- };
-
- template <typename T, typename D = T> class TypedTarget : public InstanceTarget {
- public:
- TypedTarget(T * t, const D & d) :
- target(t),
- defValue(d) {
- }
- TypedTarget(T * t) :
- target(t),
- defValue(T()) {
- }
- void reset() const {
- ts = Default;
- *target = defValue;
- }
- void assign(const VariableType & value) const {
- doAssign(value);
- }
- protected:
- T * target;
- private:
- template <typename dummy = int>
- void doAssign(const VariableType & value,
- typename boost::disable_if<std::is_assignable<T, VariableType>, dummy>::type = 0,
- typename boost::disable_if<std::is_convertible<VariableType, T>, dummy>::type = 0) const {
- *target = boost::lexical_cast<T>(value.as<Glib::ustring>());
- }
- template <typename dummy = int>
- void doAssign(const VariableType & value,
- typename boost::enable_if<std::is_convertible<VariableType, T>, dummy>::type = 0) const {
- *target = value.as<T>();
- }
- template <typename dummy = int>
- void doAssign(const VariableType & value,
- typename boost::disable_if<std::is_convertible<VariableType, T>, dummy>::type = 0,
- typename boost::enable_if<std::is_assignable<T, VariableType>, dummy>::type = 0) const {
- *target = value;
- }
- D defValue;
- };
-
- template <typename T> class TypedTarget<std::vector<T> > : public InstanceTarget {
- public:
- typedef std::vector<T> VofT;
- TypedTarget(VofT * t) :
- target(t) {
- }
- void reset() const {
- ts = Default;
- target->clear();
- }
- void assign(const VariableType & value) const {
- doAssign(value);
- }
- protected:
- VofT * target;
- private:
- template <typename dummy = int>
- void doAssign(const VariableType & value, typename boost::disable_if<std::is_constructible<T, VariableType>, dummy>::type = 0) const {
- target->push_back(boost::lexical_cast<T>(value.as<Glib::ustring>()));
- }
- template <typename dummy = int>
- void doAssign(const VariableType & value, typename boost::enable_if<std::is_constructible<T, VariableType>, dummy>::type = 0) const {
- target->push_back(T(value));
- }
+ Assigner assigner;
+ Resetter resetter;
};
class Option : public IntrusivePtrBase {
@@ -140,20 +54,34 @@ class Options {
Options & operator()(const Glib::ustring & optionName, TargetPtr target, const Glib::ustring & description);
Options & operator()(const Glib::ustring & optionName);
Options & operator()(OptionPtr);
- template <typename T>
+
+ template <typename T, typename D = T, typename dummy = int>
static
- TargetPtr value(T * t) {
- return new TypedTarget<T>(t);
+ TargetPtr value(T * t, const D & d = D(),
+ typename boost::enable_if<std::is_convertible<VariableType, T>, dummy>::type = 0) {
+ return new InstanceTarget(
+ [t](const VariableType & v) { *t = v.as<T>(); },
+ [t, d]() { *t = d; });
}
- template <typename T, typename D>
+
+ template <typename T, typename D = T, typename dummy = int>
static
- TargetPtr value(T * t, const D & d) {
- return new TypedTarget<T>(t, d);
+ TargetPtr value(T * t, const D & d = D(),
+ typename boost::disable_if<std::is_convertible<VariableType, T>, dummy>::type = 0) {
+ return new InstanceTarget(
+ [t](const VariableType & v) { *t = v; },
+ [t, d]() { *t = d; });
}
- template <typename T, typename D>
+
+ template <typename D>
+ static
+ TargetPtr function(const Assigner & assigner, const D & d) {
+ return new InstanceTarget(assigner, boost::bind(assigner, d));
+ }
+
static
- TargetPtr valueConvert(T * t, const D & d) {
- return new TypedTarget<T, D>(t, d);
+ TargetPtr functions(const Assigner & assigner, const Resetter & resetter) {
+ return new InstanceTarget(assigner, resetter);
}
void reset() const;
diff --git a/project2/console/consoleEnvironment.cpp b/project2/console/consoleEnvironment.cpp
index 2420e35..28da574 100644
--- a/project2/console/consoleEnvironment.cpp
+++ b/project2/console/consoleEnvironment.cpp
@@ -17,15 +17,6 @@ int ConsoleEnvironment::argc;
char ** ConsoleEnvironment::argv;
ConsoleEnvironment::ToDoList ConsoleEnvironment::todolist;
-template<typename _CharT, typename _Traits>
-std::basic_istream<_CharT, _Traits> &
-operator>>(std::basic_istream<_CharT, _Traits> & s, ConsoleEnvironment::QueryParams::value_type & q)
-{
- std::getline(s, q.first, '=');
- std::getline(s, q.second);
- return s;
-}
-
class ShowHelpTrigger : public Options::Target {
public:
void reset() const { }
@@ -48,7 +39,12 @@ ConsoleEnvironment::ConsoleEnvironment(int c, char ** v) :
("help", new ShowHelpTrigger(), "Print usage and exit")("h")
("console.syslogIdent", Options::value(&scriptname, scriptname), "Log to syslog with ident <arg>")
("console.platform", Options::value(&reqPlatform), "Platform")("p")
- ("console.queryParam", Options::value(&queryParams), "Query parameter")("q")
+ ("console.queryParam", Options::functions(
+ [this](const VariableType & v) {
+ Glib::ustring vs(v.as<Glib::ustring>());
+ queryParams.push_back(QueryParams::value_type(vs.substr(0, vs.find('=')), vs.substr(vs.find('=') + 1)));
+ },
+ boost::bind(&QueryParams::clear, &queryParams)), "Query parameter")("q")
;
}
diff --git a/project2/json/couchSession.cpp b/project2/json/couchSession.cpp
index 7045113..2fe2ae6 100644
--- a/project2/json/couchSession.cpp
+++ b/project2/json/couchSession.cpp
@@ -111,7 +111,9 @@ class CustomCouchSessionLoader : public SessionContainerLoader::For<CouchSession
opts("Session CouchDB options")
{
opts
- ("session.couchdb.baseUrl", Options::value(&CouchSessionContainer::baseUrls),
+ ("session.couchdb.baseUrl", Options::functions(
+ [](const VariableType & v) { CouchSessionContainer::baseUrls.push_back(v); },
+ boost::bind(&std::vector<std::string>::clear, &CouchSessionContainer::baseUrls)),
"Base URL to store sessions in")
;
}