diff options
| -rw-r--r-- | project2/cgi/cgiContentNegotiate.cpp | 18 | ||||
| -rw-r--r-- | project2/cgi/cgiProgRouter.cpp | 11 | ||||
| -rw-r--r-- | project2/common/options.cpp | 25 | ||||
| -rw-r--r-- | project2/common/options.h | 138 | ||||
| -rw-r--r-- | project2/console/consoleEnvironment.cpp | 16 | ||||
| -rw-r--r-- | project2/json/couchSession.cpp | 4 | 
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")  				;  		} | 
