Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Changeset 1664


Ignore:
Timestamp:
Aug 21, 2008, 9:23:11 PM (16 years ago)
Author:
rgrieder
Message:
  • Finished CommandLineArgument completely. You can also use SetCommandLineSwitch to define boolean switches.
  • Added StaticConversion to Covert.h (compile time type conversion checking)
  • Fixed a bug in Exception
  • Added getAllStrings() to SubString
Location:
code/branches/gui/src
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • code/branches/gui/src/core/CommandLine.cc

    r1663 r1664  
    3131namespace orxonox
    3232{
     33    /**
     34    @brief
     35        Destructor destroys all CommandLineArguments with it.
     36    */
    3337    CommandLine::~CommandLine()
    3438    {
     
    3943        }
    4044    }
    41    
     45
     46    /**
     47    @brief
     48        Returns a unique instance (Meyers Singleton).
     49    */
    4250    CommandLine& CommandLine::_getInstance()
    4351    {
     
    4654    }
    4755
    48     void CommandLine::_parse(int argc, char** argv)
    49     {
     56    /**
     57    @brief
     58        Reads the command line parses the values of each argument.
     59        It is then stored in the corresponding CommandLineArgument.
     60    @note
     61        The reason that you have to provide the string to be parsed as
     62        space separted list is because of argc and argv. If you only have
     63        a whole string, simply use getAllStrings() of SubString.
     64    @param arguments
     65        Vector of space separated strings.
     66    */
     67    void CommandLine::_parse(const std::vector<std::string>& arguments)
     68    {
     69        // why this? See bFirstTimeParse_ declaration.
    5070        if (bFirstTimeParse_)
    5171        {
     
    6484        std::string name;
    6585        std::string shortcut;
    66         std::string val;
    67         for (int i = 1; i < argc; ++i)
    68         {
    69             if (argv[i][0] == '-')
     86        std::string value;
     87        for (unsigned int i = 0; i < arguments.size(); ++i)
     88        {
     89            if (arguments[i].size() != 0)
    7090            {
    71                 if (argv[i][1] <= 57 && argv[i][1] >= 48)
     91                // sure not ""
     92                if (arguments[i][0] == '-')
    7293                {
    73                     // negative number as a value
    74                     val += std::string(argv[i]) + " ";
     94                    // start with "-"
     95                    if (arguments[i].size() == 1)
     96                    {
     97                        // argument[i] is "-", probably a minus sign
     98                        value += "- ";
     99                    }
     100                    else if (arguments[i][1] <= 57 && arguments[i][1] >= 48)
     101                    {
     102                        // negative number as a value
     103                        value += arguments[i] + " ";
     104                    }
     105                    else
     106                    {
     107                        // can be shortcut or full name argument
     108
     109                        // save old data first
     110                        if (name != "")
     111                        {
     112                            checkFullArgument(name, value);
     113                            name = "";
     114                            assert(shortcut == "");
     115                        }
     116                        else if (shortcut != "")
     117                        {
     118                            checkShortcut(shortcut, value);
     119                            shortcut = "";
     120                            assert(name == "");
     121                        }
     122
     123                        if (arguments[i][1] == '-')
     124                        {
     125                            // full name argument with "--name"
     126                            name = arguments[i].substr(2);
     127                        }
     128                        else
     129                        {
     130                            // shortcut with "-s"
     131                            shortcut = arguments[i].substr(1);
     132                        }
     133
     134                        // reset value string
     135                        value = "";
     136                    }
    75137                }
    76138                else
    77139                {
    78                     // save old data first
    79                     if (name != "")
    80                     {
    81                         checkFullArgument(name, val);
    82                         name = "";
    83                         assert(shortcut == "");
    84                     }
    85                     else if (shortcut != "")
    86                     {
    87                         checkShortcut(shortcut, val);
    88                         shortcut = "";
    89                         assert(name == "");
    90                     }
    91 
    92                     if (argv[i][1] == '-')
    93                     {
    94                         // full name argument
    95                         name = argv[i] + 2;
    96                     }
    97                     else
    98                     {
    99                         // short cut
    100                         shortcut = argv[i] + 1;
    101                     }
    102                     val = "";
     140                    // value string
     141
     142                    if (name == "" && shortcut == "")
     143                    {
     144                        ThrowException(Argument, "Expected \"-\" or \"-\" in command line arguments.\n");
     145                    }
     146
     147                    // Concatenate strings as long as there's no new argument by "-" or "--"
     148                    value += arguments[i] + ' ';
    103149                }
    104150            }
    105             else // value
    106             {
    107                 if (name == "" && shortcut == "")
    108                 {
    109                     ThrowException(Argument, "Expected \"-\" or \"-\" in command line arguments.\n");
    110                 }
    111 
    112                 val += argv[i];
    113             }
    114         }
    115     }
    116 
     151        }
     152
     153        // parse last argument
     154        if (name != "")
     155        {
     156            checkFullArgument(name, value);
     157            assert(shortcut == "");
     158        }
     159        else if (shortcut != "")
     160        {
     161            checkShortcut(shortcut, value);
     162            assert(name == "");
     163        }
     164    }
     165
     166    /**
     167    @brief
     168        Parses an argument based on its full name.
     169    @param name
     170        Full name of the argument
     171    @param value
     172        String containing the value
     173    */
    117174    void CommandLine::checkFullArgument(const std::string& name, const std::string& value)
    118175    {
     
    124181    }
    125182
     183    /**
     184    @brief
     185        Parses an argument based on its shortcut.
     186    @param shortcut
     187        Shotcut to the argument
     188    @param value
     189        String containing the value
     190    */
    126191    void CommandLine::checkShortcut(const std::string& shortcut, const std::string& value)
    127192    {
     
    132197        it->second->parse(value);
    133198    }
     199
     200    std::string CommandLine::getUsageInformation()
     201    {
     202        CommandLine* inst = &_getInstance();
     203        std::string infoStr;
     204        for (std::map<std::string, BaseCommandLineArgument*>::const_iterator it = inst->cmdLineArgs_.begin();
     205            it != inst->cmdLineArgs_.end(); ++it)
     206        {
     207            infoStr += "[--" + it->second->getName() + " " + it->second->getInformation() + "] ";
     208        }
     209        return infoStr;
     210    }
     211
    134212}
  • code/branches/gui/src/core/CommandLine.h

    r1663 r1664  
    3636#include "Exception.h"
    3737
    38 
    3938#define SetCommandLineArgument(name, defaultValue) \
    4039    BaseCommandLineArgument& CmdArgumentDummyBoolVar##name \
    4140    = orxonox::CommandLine::addCommandLineArgument(#name, defaultValue)
     41#define SetCommandLineSwitch(name) \
     42    BaseCommandLineArgument& CmdArgumentDummyBoolVar##name \
     43    = orxonox::CommandLine::addCommandLineArgument(#name, false)
     44
    4245
    4346namespace orxonox
    4447{
     48    /**
     49    @brief
     50        Template struct which creates a distinct type for every integer constant.
     51    @note
     52        This allows to select a different function depending on a boolean value
     53        when creating a new CommandLineArgument.
     54        From 'Modern C++ Design' (Alexandrescu 2001).
     55    */
     56    template <int v>
     57    struct Int2Type
     58    {
     59        enum { value = v };
     60    };
     61
     62    /**
     63    @brief
     64        Base class for CommandLineArguments.
     65    */
    4566    class _CoreExport BaseCommandLineArgument
    4667    {
     
    4869
    4970    public:
     71        //! Tells whether the value has been changed by the command line.
    5072        bool hasDefaultValue() const { return bHasDefaultValue_; }
     73        //! Returns the name of the argument.
    5174        const std::string& getName() const { return name_; }
     75
     76        //! Returns the shortcut (example: "-p 22" for "--port 22") of the argument.
     77        //! Evaluates to "" if none there is none.
    5278        const std::string& getShortcut() const { return shortcut_; }
     79        //! Sets the shortcut for the argument
    5380        BaseCommandLineArgument& setShortcut(const std::string& shortcut)
    5481        { this->shortcut_ = shortcut; return *this; }
     82
     83        //! Returns the usage information
     84        const std::string& getInformation() const { return this->usageInformation_; }
     85        //! Sets the option information when displaying orxonox usage.
     86        BaseCommandLineArgument& setInformation(const std::string& usage)
     87        { this->usageInformation_ = usage; return *this; }
    5588
    5689    protected:
     
    6093        { }
    6194
     95        //! Undefined copy constructor
    6296        BaseCommandLineArgument(const BaseCommandLineArgument& instance);
    6397        virtual ~BaseCommandLineArgument() { }
    6498
     99        //! Parses the value string of a command line argument.
    65100        virtual void parse(const std::string& value) = 0;
    66101
     102        //! Tells whether the value has been changed by the command line.
    67103        bool bHasDefaultValue_;
    68104
    69105    private:
    70         std::string name_;
    71         std::string shortcut_;
     106        std::string name_;             //!< Name of the argument
     107        std::string shortcut_;         //!< Shortcut of the argument. @see getShortcut().
     108        std::string usageInformation_; //!< Tells about the usage of this parameter
    72109    };
    73110
    74111
     112    /**
     113    @brief
     114        Container class for a command line argument of type T.
     115       
     116        Whenever you want to have an option specified by a command line switch,
     117        you need to first define it with SetCommandLineArgument(name, defaultValue).
     118        It is then added to a map and possibly changed when the command line is being parsed.
     119        If the option was not given, you can detect this by asking hasDefaultValue().
     120       
     121        There is a possibility to define a short cut so you can write "-p 20" instead of "--port 20".
     122        Note the difference between "-" and "--"!
     123        Also, there is no restriction to the number of strings you add after --name.
     124        So "--startVector (2, 4, 5)" is perfectly legal.
     125
     126        Retrieving an argument is possible with the getCommandLineArgument function of the
     127        CommandLine class. It is a Singleton, but the public interface is static.
     128    */
    75129    template <class T>
    76130    class CommandLineArgument : public BaseCommandLineArgument
    77131    {
     132        // Only let CommandLine change the value.
    78133        friend class CommandLine;
    79134
    80135    public:
     136        //! Returns the actual value of the argument. Can be equal to default value.
    81137        T getValue() const { return value_; }
     138        //! Returns the given default value as type T.
    82139        T getDefaultValue() const { return defaultValue_; }
    83140
    84141    private:
     142        //! Constructor initialises both value_ and defaultValue_ with defaultValue.
    85143        CommandLineArgument(const std::string& name, const T& defaultValue)
    86144            : BaseCommandLineArgument(name)
     
    91149        virtual void parse(const std::string& value);
    92150
    93         T value_;
    94         T defaultValue_;
     151        T value_;            //!< The actual value
     152        T defaultValue_;     //!< Default value. Should not be changed.
    95153    };
    96154
     155    /**
     156    @brief
     157        Parses a value string for a command line argument.
     158        It simply uses convertValue(Output, Input) to do that.
     159    */
    97160    template <class T>
    98161    void CommandLineArgument<T>::parse(const std::string& value)
     
    108171    }
    109172
    110 
     173    /**
     174    @brief
     175        Parses a value string for a command line argument.
     176        It simply uses convertValue(Output, Input) to do that.
     177        This is a template specialisation for bool type. That is necessary
     178        so that you can have simple command line switches.
     179    */
     180    template <>
     181    inline void CommandLineArgument<bool>::parse(const std::string& value)
     182    {
     183        if (convertValue(&this->value_, value))
     184        {
     185            this->bHasDefaultValue_ = false;
     186        }
     187        else if (value == "")
     188        {
     189            this->bHasDefaultValue_ = false;
     190            this->value_ = true;
     191        }
     192        else
     193        {
     194            ThrowException(Argument, "Could not read command line argument '" + getName() + "'.");
     195        }
     196    }
     197
     198
     199    /**
     200    @brief
     201        Global interface to command line options.
     202        Allows to add and retrieve command line arguments. Also does the parsing.
     203    @note
     204        Internally it is a Singleton, but the public interface is static.
     205    @see
     206        CommandLineArgument
     207    */
    111208    class _CoreExport CommandLine
    112209    {
    113210    public:
    114211
    115         static void parse(int argc, char** argv) { _getInstance()._parse(argc, argv); }
     212        //! Parse redirection to internal member method.
     213        static void parse(const std::vector<std::string>& arguments) { _getInstance()._parse(arguments); }
     214
     215        static std::string getUsageInformation();
    116216
    117217        template <class T>
    118218        static const CommandLineArgument<T>* getCommandLineArgument(const std::string& name);
    119         template <class T>
    120         static BaseCommandLineArgument& addCommandLineArgument(const std::string& name,
    121             const T& defaultValue);
     219        //! Writes the argument value in the given parameter.
     220        template <class T>
     221        static void getCommandLineValue(const std::string& name, T* value)
     222        { *value = getCommandLineArgument<T>(name)->getValue(); }
     223        template <class T>
     224        static BaseCommandLineArgument& addCommandLineArgument(const std::string& name, T defaultValue);
    122225
    123226    private:
     227        //! Constructor initialises bFirstTimeParse_ with true.
    124228        CommandLine() : bFirstTimeParse_(true) { }
     229        //! Undefined copy constructor
    125230        CommandLine(const CommandLine& instance);
    126231        ~CommandLine();
     
    128233        static CommandLine& _getInstance();
    129234
    130         void _parse(int argc, char** argv);
     235        void _parse(const std::vector<std::string>& arguments);
    131236        void checkFullArgument(const std::string& name, const std::string& value);
    132237        void checkShortcut(const std::string& shortcut, const std::string& value);
    133238
     239        template <class T>
     240        BaseCommandLineArgument* createArg(const std::string& name, T defaultValue, Int2Type<0> isString);
     241        template <class T>
     242        BaseCommandLineArgument* createArg(const std::string& name, T defaultValue, Int2Type<1> isString);
     243
     244        /**
     245            Tells whether we parse the first expression. The CommmandLineArguments are added before main().
     246            So when we call parse() the first time, we need to create a map with all shortcuts since these
     247            get added after addCommandLineArgument().
     248        */
    134249        bool bFirstTimeParse_;
    135250
     251        //! Holds all pointers to the arguments and serves as a search map by name.
    136252        std::map<std::string, BaseCommandLineArgument*> cmdLineArgs_;
     253        //! Search map by chortcut for the arguments.
    137254        std::map<std::string, BaseCommandLineArgument*> cmdLineArgsShortcut_;
    138255    };
    139256
    140257
     258    /**
     259    @brief
     260        Retrieves a CommandLineArgument.
     261        The method throws an exception if 'name' was not found or the value could not be converted.
     262    @note
     263        You shold of course not call this method before the command line has been parsed.
     264    */
    141265    template <class T>
    142266    const CommandLineArgument<T>* CommandLine::getCommandLineArgument(const std::string& name)
     
    162286    }
    163287
    164     template <class T>
    165     BaseCommandLineArgument& CommandLine::addCommandLineArgument(const std::string& name,
    166                                              const T& defaultValue)
     288    /**
     289    @brief
     290        Adds a new CommandLineArgument to the internal map.
     291        Note that only such arguments are actually valid.
     292    @param name
     293        Name of the argument. Shortcut can be added later.
     294    @param defaultValue
     295        Default value that is used when argument was not given.
     296    @note
     297        In order to store char* strings as std::string too, there's
     298        little bit of template programming involved:
     299        StaticConversions::exists determines whether T converts to std::string.
     300        Int2Type<int> is then used to call the right function. One returns
     301        a CommandLineArgument<T> and the other CommandLineArgument<std::string>.
     302    */
     303    template <class T>
     304    BaseCommandLineArgument& CommandLine::addCommandLineArgument(const std::string& name, T defaultValue)
    167305    {
    168306        std::map<std::string, BaseCommandLineArgument*>::const_iterator it = _getInstance().cmdLineArgs_.find(name);
     
    170308            "Cannot add a command line argument with name '" + name + "' twice.");
    171309
    172         return *(_getInstance().cmdLineArgs_[name] = new CommandLineArgument<T>(name, defaultValue));
     310        return *(_getInstance().cmdLineArgs_[name] =
     311            _getInstance().createArg(name, defaultValue, Int2Type<StaticConversion<T, std::string>::exists>()));
     312    }
     313
     314    /**
     315        Returns a new CommandLineArgument<T>.
     316    */
     317    template <class T>
     318    BaseCommandLineArgument* CommandLine::createArg(const std::string& name, T defaultValue, Int2Type<0> isPrime)
     319    {
     320        return new CommandLineArgument<T>(name, defaultValue);
     321    }
     322
     323    /**
     324        Returns a new CommandLineArgument<std::string>.
     325    */
     326    template <class T>
     327    BaseCommandLineArgument* CommandLine::createArg(const std::string& name, T defaultValue, Int2Type<1> isPrime)
     328    {
     329        return new CommandLineArgument<std::string>(name, defaultValue);
    173330    }
    174331}
  • code/branches/gui/src/core/Exception.cc

    r1638 r1664  
    5252    { }
    5353
    54     std::string Exception::getFullDescription() const
     54    const std::string& Exception::getFullDescription() const
    5555    {
    56         std::ostringstream fullDesc;
     56        if (fullDescription_ == "")
     57        {
     58            std::ostringstream fullDesc;
    5759
    58         fullDesc << this->getTypeName() << "_EXCEPTION";
     60            fullDesc << this->getTypeName() << "_EXCEPTION";
    5961
    60         if (this->fileName_ != "")
    61         {
    62             fullDesc << " in " << this->fileName_;
    63             if (this->lineNumber_)
    64                 fullDesc << "(" << this->lineNumber_ << ")";
     62            if (this->fileName_ != "")
     63            {
     64                fullDesc << " in " << this->fileName_;
     65                if (this->lineNumber_)
     66                    fullDesc << "(" << this->lineNumber_ << ")";
     67            }
     68
     69            if (this->functionName_ != "")
     70                fullDesc << " in function '" << this->functionName_ << "'";
     71
     72            fullDesc << ": ";
     73            if (this->description_ != "")
     74                fullDesc << this->description_;
     75            else
     76                fullDesc << "No description available.";
     77
     78            this->fullDescription_ = std::string(fullDesc.str());
    6579        }
    6680
    67         if (this->functionName_ != "")
    68             fullDesc << " in function '" << this->functionName_ << "'";
    69 
    70         fullDesc << ": ";
    71         if (this->description_ != "")
    72             fullDesc << this->description_;
    73         else
    74             fullDesc << "No description available.";
    75 
    76         return fullDesc.str();
     81        return fullDescription_;
    7782    }
    7883
  • code/branches/gui/src/core/Exception.h

    r1663 r1664  
    7373        virtual ~Exception() throw() { }
    7474
    75         virtual std::string        getFullDescription() const;
     75        virtual const std::string& getFullDescription() const;
    7676        virtual ExceptionType      getType()            const = 0;
    7777        virtual std::string        getTypeName()        const = 0;
     
    8888        std::string functionName_;
    8989        std::string fileName_;
     90        // mutable because of "what()" is a const method
     91        mutable std::string fullDescription_;
    9092    };
    9193
  • code/branches/gui/src/orxonox/Main.cc

    r1663 r1664  
    4141#include "core/SignalHandler.h"
    4242#include "core/Debug.h"
    43 #include "core/CommandLine.h"
    44 //#include "Orxonox.h"
    4543
    4644#include "gamestates/GSRoot.h"
     
    8583int main(int argc, char** argv)
    8684{
    87     try
    88     {
    89         orxonox::CommandLine::parse(argc, argv);
    90     }
    91     catch (orxonox::ArgumentException& ex)
    92     {
    93         COUT(1) << ex.what() << std::endl;
    94         COUT(0) << "Usage:" << std::endl << "orxonox [--mode client|server|dedicated|standalone] "
    95                 << "[--data PATH] [--ip IP] [--port PORT]" << std::endl;
    96     }
    97 
    98 
    9985    // create a signal handler (only works for linux)
    10086    SignalHandler::getInstance()->doCatch(argv[0], "orxonox.log");
    101 
    10287
    10388
     
    144129    graphics.addChild(&gui);
    145130
    146     root.requestState("gui");
     131    root.feedCommandLine(argc, argv);
     132    root.requestState("root");
    147133    root.tick(0.0f);
    148134    root.requestState("");
    149 
    150 
    151     //Orxonox orxonoxInstance;
    152 
    153     try
    154     {
    155 #if ORXONOX_PLATFORM == ORXONOX_PLATFORM_APPLE
    156         orxonoxInstance.start(macBundlePath());
    157 #else
    158         //orxonoxInstance.start();
    159 #endif
    160     }
    161     catch (std::exception& ex)
    162     {
    163         COUT(1) << ex.what() << std::endl;
    164         COUT(1) << "Abort." << std::endl;
    165     }
    166135
    167136    return 0;
  • code/branches/gui/src/orxonox/gamestates/GSLevel.cc

    r1663 r1664  
    4646namespace orxonox
    4747{
    48     SetCommandLineArgument(port, 55556).setShortcut("p");
    49     SetCommandLineArgument(ip, std::string("127.0.0.0"));
     48    SetCommandLineArgument(port, 55556).setShortcut("p").setInformation("PORT");
     49    SetCommandLineArgument(ip, "127.0.0.0").setInformation("#.#.#.#");
    5050
    5151    GSLevel::GSLevel()
  • code/branches/gui/src/orxonox/gamestates/GSRoot.cc

    r1663 r1664  
    3030#include "GSRoot.h"
    3131
     32#include "util/SubString.h"
    3233#include "core/Factory.h"
    3334#include "core/ConfigFileManager.h"
    3435#include "core/ConfigValueIncludes.h"
    3536#include "core/ConsoleCommand.h"
     37#include "core/CommandLine.h"
    3638#include "core/Debug.h"
    3739#include "core/Exception.h"
     
    4446namespace orxonox
    4547{
    46     SetCommandLineArgument(dataPath, std::string("./"));
     48    SetCommandLineArgument(dataPath, "").setInformation("PATH");
    4749
    4850    GSRoot::GSRoot()
     
    5557    GSRoot::~GSRoot()
    5658    {
     59    }
     60
     61    //SetCommandLineArgument(asdf1, "haha").setShortcut("a").setUsageInformation("1|2|3");
     62    //SetCommandLineArgument(asdf2, 3).setShortcut("b");
     63    //SetCommandLineArgument(asdf3, Vector2()).setShortcut("c");
     64    //SetCommandLineArgument(adsf4, 1.4f).setShortcut("d");
     65    //SetCommandLineSwitch(showGraphics).setShortcut("g");
     66
     67    void GSRoot::feedCommandLine(int argc, char** argv)
     68    {
     69        std::vector<std::string> args;
     70        for (int i = 1; i < argc; ++i)
     71            args.push_back(argv[i]);
     72
     73        //std::string line = "-a --asdf3 (3,3) -d -5 -b - 5.4";
     74        //SubString tokens(line, " ", " ", false, 92, false, 34, true, 40, 41, false, 0);
     75
     76        try
     77        {
     78            orxonox::CommandLine::parse(args);
     79            //CommandLine::parse(tokens.getAllStrings());
     80        }
     81        catch (orxonox::ArgumentException& ex)
     82        {
     83            COUT(1) << ex.what() << std::endl;
     84            COUT(0) << "Usage:" << std::endl << "orxonox " << CommandLine::getUsageInformation() << std::endl;
     85        }
    5786    }
    5887
     
    71100        this->settings_ = new Settings();
    72101
    73         const CommandLineArgument<std::string>* dataPath = CommandLine::getCommandLineArgument<std::string>("dataPath");
    74         if (!dataPath->hasDefaultValue())
     102        std::string dataPath;
     103        CommandLine::getCommandLineValue("dataPath", &dataPath);
     104        if (dataPath != "")
    75105        {
    76             if (*dataPath->getValue().end() != '/' && *dataPath->getValue().end() != '\\')
    77                 Settings::tsetDataPath(dataPath->getValue() + "/");
     106            if (*dataPath.end() != '/' && *dataPath.end() != '\\')
     107                Settings::tsetDataPath(dataPath + "/");
    78108            else
    79                 Settings::tsetDataPath(dataPath->getValue());
     109                Settings::tsetDataPath(dataPath);
    80110        }
    81111
     
    91121        functor->setObject(this);
    92122        CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(functor, "loadGame"));
     123
     124        requestState("gui");
    93125    }
    94126
  • code/branches/gui/src/orxonox/gamestates/GSRoot.h

    r1663 r1664  
    4141        ~GSRoot();
    4242
     43        void feedCommandLine(int argc, char** argv);
    4344        bool tick(float dt);
    4445        void loadGame(const std::string& name);
  • code/branches/gui/src/util/Convert.h

    r1625 r1664  
    690690};
    691691
     692
     693///////////////////////////
     694// Static type detection //
     695///////////////////////////
     696
     697/**
     698    Template class that determines whether type T converts implicitly to type U.
     699@note
     700    This allows to detect type conversion at compile time.
     701    From 'Modern C++ Design' (Alexandrescu 2001).
     702*/
     703template <class T, class U>
     704class StaticConversion
     705{
     706    class Small { char dummy[1]; };
     707    class Big   { char dummy[1024]; };
     708    static Small Test(U);
     709    static Big   Test(...);
     710    static T MakeT();
     711public:
     712    enum { exists = sizeof(Test(MakeT())) == sizeof(Small) };
     713};
     714
    692715#if ORXONOX_COMPILER == ORXONOX_COMPILER_MSVC
    693716#pragma warning(pop)
  • code/branches/gui/src/util/SubString.h

    r1505 r1664  
    131131  /** @brief Returns the i'th string from the subset of Strings @param i the i'th String */
    132132  inline const std::string& getString(unsigned int i) const { return (*this)[i]; };
     133  /** @brief Returns all Strings as std::vector */
     134  inline const std::vector<std::string>& getAllStrings() const { return this->strings; }
    133135  /** @brief Returns true if the token is in safemode. @param i the i'th token */
    134136  inline bool isInSafemode(unsigned int i) const { return this->bInSafemode[i]; }
Note: See TracChangeset for help on using the changeset viewer.