Sirikata
libcore/include/sirikata/core/util/FactoryWithOptions.hpp
Go to the documentation of this file.
00001 /*  Sirikata Utilities -- Sirikata Utilities
00002  *  FactoryWithOptions.hpp
00003  *
00004  *  Copyright (c) 2009, Daniel Reiter Horn
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions are
00009  *  met:
00010  *  * Redistributions of source code must retain the above copyright
00011  *    notice, this list of conditions and the following disclaimer.
00012  *  * Redistributions in binary form must reproduce the above copyright
00013  *    notice, this list of conditions and the following disclaimer in
00014  *    the documentation and/or other materials provided with the
00015  *    distribution.
00016  *  * Neither the name of Sirikata nor the names of its contributors may
00017  *    be used to endorse or promote products derived from this software
00018  *    without specific prior written permission.
00019  *
00020  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
00021  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
00022  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00023  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
00024  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00025  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00026  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00027  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00028  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00029  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00030  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00031  */
00032 
00033 #ifndef _SIRIKATA_FACTORY_WITH_OPTIONS_HPP_
00034 #define _SIRIKATA_FACTORY_WITH_OPTIONS_HPP_
00035 #include "Factory.hpp"
00036 namespace Sirikata {
00037 
00038 template<class T, class Ftype>
00039 class FactoryWithOptionsImpl :protected FactoryImpl<T,Ftype> {
00040     typedef std::tr1::function<OptionSet*(const String&)> Otype;
00041     typedef std::tr1::unordered_map<String, Otype> OptionMap;
00042     OptionMap mOptionParsers;
00043     Otype mNop;
00044     
00045     static OptionSet* staticNop() {
00046         return NULL;
00047     }
00048 
00049 public:
00050     FactoryWithOptionsImpl():mNop(std::tr1::bind(&staticNop)){}
00051     bool unregisterConstructor(const String& name) {
00052         if (FactoryImpl<T,Ftype>::unregisterConstructor(name)) {
00053             typename OptionMap::iterator where=mOptionParsers.find(name);
00054             if (where==mOptionParsers.end())
00055                 return false;
00056             mOptionParsers.erase(where);
00057         }
00058         return true;
00059     }
00060     bool hasConstructor(const String&name)const {
00061         return FactoryImpl<T,Ftype>::hasConstructor(name);
00062     }
00063     const String& getDefault()const {
00064         return FactoryImpl<T,Ftype>::getDefault();
00065     }
00066     bool registerConstructor(const String& name,
00067                              const Ftype &constructor,
00068                              const Otype &optionParser, bool defaultValue) {
00069         if (FactoryImpl<T,Ftype>::registerConstructor(name,constructor, defaultValue)) {
00070             mOptionParsers[name]=optionParser;
00071             return true;
00072         }
00073         return false;
00074     }
00075     const Otype &getOptionParser(const String&name)const {
00076         typename OptionMap::const_iterator where=mOptionParsers.find(name);
00077         if (where==mOptionParsers.end()) {
00078             if (name.length()==0&&getDefault().length()) {
00079                 return getDefaultOptionParser();
00080             }
00081             return mNop;
00082         }
00083 
00084         return where->second;
00085         
00086     }
00087     const Otype& getDefaultOptionParser()const {
00088         return getOptionParser(getDefault());
00089     }
00090     const Ftype &getConstructor(const String&name)const {
00091         return FactoryImpl<T,Ftype>::getConstructor(name);
00092     }
00093     const Ftype &getDefaultConstructor()const {
00094         return FactoryImpl<T,Ftype>::getDefaultConstructor();
00095     }
00096     
00097 };
00098 
00099 template <class T>class FactoryWithOptions:public FactoryWithOptionsImpl<T,std::tr1::function<T()> >{};
00100 
00101 template <class T, typename A>class FactoryWithOptions1:public FactoryWithOptionsImpl<T,std::tr1::function<T(A)> >{};
00102 
00103 template <class T, typename A, typename B>class FactoryWithOptions2:public FactoryWithOptionsImpl<T,std::tr1::function<T(A,B)> >{};
00104 
00105 template <class T, typename A, typename B, typename C>class FactoryWithOptions3:public FactoryWithOptionsImpl<T,std::tr1::function<T(A,B,C)> >{};
00106 
00107 template <class T, typename A, typename B, typename C, typename D>class FactoryWithOptions4:public FactoryWithOptionsImpl<T,std::tr1::function<T(A,B,C,D)> >{};
00108 
00109 template <class T, typename A, typename B, typename C, typename D, typename E>class FactoryWithOptions5:public FactoryWithOptionsImpl<T,std::tr1::function<T(A,B,C,D,E)> >{};
00110 
00111 template <class T, typename A, typename B, typename C, typename D, typename E, typename F>class FactoryWithOptions6:public FactoryWithOptionsImpl<T,std::tr1::function<T(A,B,C,D,E,F)> >{};
00112 
00113 }
00114 
00115 #endif