Sort all includes in src/gromacs
[alexxy/gromacs.git] / src / gromacs / options / optionsassigner.h
index fd81977ebe3dfcc2adee06bd8c120fac424bcb98..d56529e7074dd456457914effea8b983ae98645a 100644 (file)
@@ -1,32 +1,36 @@
 /*
+ * This file is part of the GROMACS molecular simulation package.
  *
- *                This source code is part of
+ * Copyright (c) 2010,2011,2012,2013,2014, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
  *
- *                 G   R   O   M   A   C   S
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
  *
- *          GROningen MAchine for Chemical Simulations
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
  *
- * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
- * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2009, The GROMACS development team,
- * check out http://www.gromacs.org for more information.
-
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
  *
- * If you want to redistribute modifications, please consider that
- * scientific software is very special. Version control is crucial -
- * bugs must be traceable. We will be happy to consider code for
- * inclusion in the official distribution, but derived work must not
- * be called official GROMACS. Details are found in the README & COPYING
- * files - if they are missing, get the official version at www.gromacs.org.
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
  *
  * To help us fund GROMACS development, we humbly ask that you cite
- * the papers on the package - you can find them in the top README file.
- *
- * For more info, check our website at http://www.gromacs.org
+ * the research papers on the package. Check out http://www.gromacs.org.
  */
 /*! \libinternal \file
  * \brief
@@ -34,7 +38,7 @@
  *
  * This header is only needed when implementing option parsers.
  *
- * \author Teemu Murtola <teemu.murtola@cbr.su.se>
+ * \author Teemu Murtola <teemu.murtola@gmail.com>
  * \inlibraryapi
  * \ingroup module_options
  */
 
 #include <string>
 
+#include "gromacs/utility/common.h"
+
 namespace gmx
 {
 
-class AbstractErrorReporter;
-
 class Options;
 
 /*! \libinternal \brief
@@ -56,33 +60,27 @@ class Options;
  * This class extends the interface of an Options object by providing methods
  * to set values for options.  It also keeps track of necessary state variables
  * to assign values to options in subsections within the Options object.
- * Typical use (without error checking):
+ * Typical use (without error handling):
  * \code
-gmx::options::Options options("name", "Title");
-// Set up options
+   gmx::Options options("name", "Title");
+   // Set up options
 
-gmx::error::StandardReporter errors;
-gmx::options::OptionsAssigner assigner(&options, &errors);
-assigner.startOption("opt1");
-assigner.appendValue("3");
-assigner.startSubSection("section");
-assigner.startOption("opt2"); // Now in the subsection
-assigner.appendValue("yes");
-assigner.finishSubSection()
-assigner.startOption("opt3"); // Again in the main options
-assigner.appendValue("2");
-assigner.finish(); // At minimum, the return value of finish() should be checked.
+   gmx::OptionsAssigner assigner(&options);
+   assigner.start();
+   assigner.startOption("opt1");
+   assigner.appendValue("3");
+   assigner.finishOption();
+   assigner.startSubSection("section");
+   assigner.startOption("opt2"); // Now in the subsection
+   assigner.appendValue("yes");
+   assigner.finishOption();
+   assigner.finishSubSection()
+   assigner.startOption("opt3"); // Again in the main options
+   assigner.appendValue("2");
+   assigner.finishOption();
+   assigner.finish();
  * \endcode
  *
- * As shown in the example, calling finishOption() or finishSubSection() is
- * optional; they are automatically called when appropriate by startOption(),
- * startSubSection(), and finish().
- * However, you need to call them explicitly if you want to act on the return
- * value: these calls do not influence the return value of
- * startOption() / startSubSection().
- * They do influence the return value of finish(), however.
- * The finish() method should always be called.
- *
  * \inlibraryapi
  * \ingroup module_options
  */
@@ -92,18 +90,9 @@ class OptionsAssigner
         /*! \brief
          * Creates an object that assigns to the given object.
          */
-        OptionsAssigner(Options *options, AbstractErrorReporter *errors);
+        explicit OptionsAssigner(Options *options);
         ~OptionsAssigner();
 
-        /*! \brief
-         * Returns the error reporter object passed to the constructor.
-         *
-         * This method is provided for convenience such that users of this
-         * class do not need to store a separate pointer to the error reporter
-         * if they need to use it.
-         */
-        AbstractErrorReporter *errorReporter() const;
-
         /*! \brief
          * Sets the assigner to recognize boolean options with a "no" prefix.
          *
@@ -116,8 +105,10 @@ class OptionsAssigner
          *
          * Can be set or cleared at any time, and will have effect on all
          * subsequent calls of startOption().
+         *
+         * Does not throw.
          */
-        void setAcceptBooleanNoPrefix(bool enabled);
+        void setAcceptBooleanNoPrefix(bool bEnabled);
         /*! \brief
          * Sets the assigner to find options in non-active sections.
          *
@@ -130,75 +121,99 @@ class OptionsAssigner
          *
          * Can be set or cleared at any time, and will have effect on all
          * subsequent calls of startOption().
+         *
+         * Does not throw.
          */
-        void setNoStrictSectioning(bool enabled);
+        void setNoStrictSectioning(bool bEnabled);
 
         /*! \brief
-         * Start assigning values.
+         * Starts assigning values.
          *
-         * \retval 0 on success.
+         * Does not throw.
          */
-        int start();
+        void start();
         /*! \brief
-         * Start assigning values to options in a subsection.
+         * Starts assigning values to options in a subsection.
          *
          * \param[in] name  Name of the subsection to start assigning to.
-         * \retval 0 if assignment can proceed.
+         * \throws InvalidInputError if such a subsection is not found.
+         *
+         * Strong exception safety guarantee.
+         */
+        void startSubSection(const char *name);
+        /*! \brief
+         * Starts assigning values for an option.
          *
-         * Does not call finishSubSection() automatically to enable nested
-         * sections.
+         * \param[in] name  Name of the option to start assigning to.
+         * \throws InvalidInputError if such an option is not found, or if the
+         *      option is specified more than once but doesn't support it.
          */
-        int startSubSection(const char *name);
+        void startOption(const char *name);
         /*! \brief
-         * Start assigning values for an option.
+         * Starts assigning values for an option.
          *
          * \param[in] name  Name of the option to start assigning to.
-         * \retval 0 if assignment can proceed.
+         * \returns   true if \p name is a valid option name.
+         * \throws InvalidInputError if the option is specified more than once
+         *      but doesn't support it.
          */
-        int startOption(const char *name);
+        bool tryStartOption(const char *name);
         /*! \brief
          * Appends a value to the value list of the current option.
          *
          * \param[in] value  String representation of the value to assign.
-         * \retval 0 if assignment was successful.
+         * \throws InvalidInputError if the value cannot be converted or if
+         *      there are too many values for an option.
+         *
+         * Basic exception safety guarantee:
+         * If this method throws, erroneous values are ignored, but it is
+         * possible to continue assigning values to the same option.  However,
+         * if \p value would result in more than one value, and some of them
+         * can be converted, but some result in errors, it is currently
+         * possible that some values have been added to the option even if an
+         * exception is thrown.
+         *
+         * Strong exception safety guarantee if the option provides value
+         * conversion with the same guarantee.  All options where a single
+         * input value always results in a single output value provide this.
+         *
+         * \internal
+         * This method provides the same exception safety guarantee as the
+         * OptionStorageTemplate::convertValue() method of the storage class
+         * implementing the option where the value is assigned to.
          */
-        int appendValue(const std::string &value);
+        void appendValue(const std::string &value);
         /*! \brief
          * Finish assigning values for the current option.
          *
-         * \retval 0 if there were no errors in the assignment.
+         * \throws InvalidInputError if the set of values since startOption()
+         *      is not valid.
+         *
+         * If this method throws, it returns to the state where the option was
+         * before startOption(), i.e., all values added with appendValue()
+         * since the last startOption() are discarded.
          *
-         * This function returns non-zero only if the error could not have been
-         * detected earlier, i.e., from the return value of appendValue().
+         * Independent of whether the method throws, the option opened with
+         * startOption() will be closed after the call.
          */
-        int finishOption();
+        void finishOption();
         /*! \brief
          * Finish assigning values to a subsection.
          *
-         * \retval 0 for success.
-         *
-         * This function returns non-zero only if the error could not have been
-         * detected earlier.
+         * Does not throw.
          */
-        int finishSubSection();
+        void finishSubSection();
         /*! \brief
          * Finish assigning options through the object.
          *
-         * \retval 0 if there were no errors in the assignment.
-         *
-         * If an error was detected in any of the other calls to this class,
-         * this function returns the error code of the first of such errors.
+         * Does not throw.
          */
-        int finish();
+        void finish();
 
     private:
         class Impl;
 
-        Impl                   *_impl;
-
-        // Disallow copy and assign.
-        OptionsAssigner(const OptionsAssigner &);
-        void operator =(const OptionsAssigner &);
+        PrivateImplPointer<Impl> impl_;
 };
 
 } // namespace gmx