Sort all includes in src/gromacs
[alexxy/gromacs.git] / src / gromacs / options / basicoptions.cpp
index 6b7c33d16ce63a5f96dbe0ed14369c3adab2cebd..412455560756b6325fa1fc173be892f898e05d84 100644 (file)
@@ -1,10 +1,10 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2010,2011,2012,2013, by the GROMACS development team, led by
- * David van der Spoel, Berk Hess, Erik Lindahl, and including many
- * others, as listed in the AUTHORS file in the top-level source
- * directory and at http://www.gromacs.org.
+ * 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.
  *
  * GROMACS is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -39,8 +39,9 @@
  * \author Teemu Murtola <teemu.murtola@gmail.com>
  * \ingroup module_options
  */
+#include "gmxpre.h"
+
 #include "basicoptions.h"
-#include "basicoptionstorage.h"
 
 #include <cerrno>
 #include <cstdio>
 #include <string>
 #include <vector>
 
+#include "gromacs/utility/cstringutil.h"
 #include "gromacs/utility/exceptions.h"
 #include "gromacs/utility/stringutil.h"
 
+#include "basicoptionstorage.h"
+
 namespace
 {
 
@@ -123,13 +127,24 @@ BooleanOptionInfo::BooleanOptionInfo(BooleanOptionStorage *option)
 {
 }
 
+const BooleanOptionStorage &BooleanOptionInfo::option() const
+{
+    return static_cast<const BooleanOptionStorage &>(OptionInfo::option());
+}
+
+bool BooleanOptionInfo::defaultValue() const
+{
+    return option().defaultValue();
+}
+
 /********************************************************************
  * BooleanOption
  */
 
-AbstractOptionStoragePointer BooleanOption::createStorage() const
+AbstractOptionStorage *
+BooleanOption::createStorage(const OptionManagerContainer & /*managers*/) const
 {
-    return AbstractOptionStoragePointer(new BooleanOptionStorage(*this));
+    return new BooleanOptionStorage(*this);
 }
 
 
@@ -184,9 +199,58 @@ IntegerOptionInfo::IntegerOptionInfo(IntegerOptionStorage *option)
  * IntegerOption
  */
 
-AbstractOptionStoragePointer IntegerOption::createStorage() const
+AbstractOptionStorage *
+IntegerOption::createStorage(const OptionManagerContainer & /*managers*/) const
+{
+    return new IntegerOptionStorage(*this);
+}
+
+
+/********************************************************************
+ * Int64OptionStorage
+ */
+
+std::string Int64OptionStorage::formatSingleValue(const gmx_int64_t &value) const
+{
+    return formatString("%" GMX_PRId64, value);
+}
+
+void Int64OptionStorage::convertValue(const std::string &value)
 {
-    return AbstractOptionStoragePointer(new IntegerOptionStorage(*this));
+    const char       *ptr = value.c_str();
+    char             *endptr;
+    errno = 0;
+    const gmx_int64_t ival = str_to_int64_t(ptr, &endptr);
+    if (errno == ERANGE)
+    {
+        GMX_THROW(InvalidInputError("Invalid value: '" + value
+                                    + "'; it causes an integer overflow"));
+    }
+    if (*ptr == '\0' || *endptr != '\0')
+    {
+        GMX_THROW(InvalidInputError("Invalid value: '" + value
+                                    + "'; expected an integer"));
+    }
+    addValue(ival);
+}
+
+/********************************************************************
+ * Int64OptionInfo
+ */
+
+Int64OptionInfo::Int64OptionInfo(Int64OptionStorage *option)
+    : OptionInfo(option)
+{
+}
+
+/********************************************************************
+ * Int64Option
+ */
+
+AbstractOptionStorage *
+Int64Option::createStorage(const OptionManagerContainer & /*managers*/) const
+{
+    return new Int64OptionStorage(*this);
 }
 
 
@@ -199,9 +263,9 @@ DoubleOptionStorage::DoubleOptionStorage(const DoubleOption &settings)
 {
 }
 
-const char *DoubleOptionStorage::typeString() const
+std::string DoubleOptionStorage::typeString() const
 {
-    return isVector() ? "vector" : (isTime() ? "time" : "double");
+    return isVector() ? "vector" : (isTime() ? "time" : "real");
 }
 
 std::string DoubleOptionStorage::formatSingleValue(const double &value) const
@@ -236,10 +300,6 @@ void DoubleOptionStorage::processSetValues(ValueList *values)
     }
 }
 
-void DoubleOptionStorage::processAll()
-{
-}
-
 void DoubleOptionStorage::setScaleFactor(double factor)
 {
     GMX_RELEASE_ASSERT(factor > 0.0, "Invalid scaling factor");
@@ -289,9 +349,114 @@ void DoubleOptionInfo::setScaleFactor(double factor)
  * DoubleOption
  */
 
-AbstractOptionStoragePointer DoubleOption::createStorage() const
+AbstractOptionStorage *
+DoubleOption::createStorage(const OptionManagerContainer & /*managers*/) const
 {
-    return AbstractOptionStoragePointer(new DoubleOptionStorage(*this));
+    return new DoubleOptionStorage(*this);
+}
+
+
+/********************************************************************
+ * FloatOptionStorage
+ */
+
+FloatOptionStorage::FloatOptionStorage(const FloatOption &settings)
+    : MyBase(settings), info_(this), bTime_(settings.bTime_), factor_(1.0)
+{
+}
+
+std::string FloatOptionStorage::typeString() const
+{
+    return isVector() ? "vector" : (isTime() ? "time" : "real");
+}
+
+std::string FloatOptionStorage::formatSingleValue(const float &value) const
+{
+    return formatString("%g", value / factor_);
+}
+
+void FloatOptionStorage::convertValue(const std::string &value)
+{
+    const char *ptr = value.c_str();
+    char       *endptr;
+    errno = 0;
+    double      dval = std::strtod(ptr, &endptr);
+    if (errno == ERANGE
+        || dval * factor_ < -std::numeric_limits<float>::max()
+        || dval * factor_ >  std::numeric_limits<float>::max())
+    {
+        GMX_THROW(InvalidInputError("Invalid value: '" + value
+                                    + "'; it causes an overflow/underflow"));
+    }
+    if (*ptr == '\0' || *endptr != '\0')
+    {
+        GMX_THROW(InvalidInputError("Invalid value: '" + value
+                                    + "'; expected a number"));
+    }
+    addValue(dval * factor_);
+}
+
+void FloatOptionStorage::processSetValues(ValueList *values)
+{
+    if (isVector())
+    {
+        expandVector(maxValueCount(), values);
+    }
+}
+
+void FloatOptionStorage::setScaleFactor(double factor)
+{
+    GMX_RELEASE_ASSERT(factor > 0.0, "Invalid scaling factor");
+    if (!hasFlag(efOption_HasDefaultValue))
+    {
+        double              scale = factor / factor_;
+        ValueList::iterator i;
+        for (i = values().begin(); i != values().end(); ++i)
+        {
+            (*i) *= scale;
+        }
+        refreshValues();
+    }
+    factor_ = factor;
+}
+
+/********************************************************************
+ * FloatOptionInfo
+ */
+
+FloatOptionInfo::FloatOptionInfo(FloatOptionStorage *option)
+    : OptionInfo(option)
+{
+}
+
+FloatOptionStorage &FloatOptionInfo::option()
+{
+    return static_cast<FloatOptionStorage &>(OptionInfo::option());
+}
+
+const FloatOptionStorage &FloatOptionInfo::option() const
+{
+    return static_cast<const FloatOptionStorage &>(OptionInfo::option());
+}
+
+bool FloatOptionInfo::isTime() const
+{
+    return option().isTime();
+}
+
+void FloatOptionInfo::setScaleFactor(double factor)
+{
+    option().setScaleFactor(factor);
+}
+
+/********************************************************************
+ * FloatOption
+ */
+
+AbstractOptionStorage *
+FloatOption::createStorage(const OptionManagerContainer & /*managers*/) const
+{
+    return new FloatOptionStorage(*this);
 }
 
 
@@ -358,11 +523,6 @@ StringOptionStorage::StringOptionStorage(const StringOption &settings)
                 GMX_THROW(APIError("Conflicting default values"));
             }
         }
-        // If there is no default value, match is still -1.
-        if (enumIndexStore_ != NULL)
-        {
-            *enumIndexStore_ = match;
-        }
     }
     if (settings.defaultEnumIndex_ >= 0)
     {
@@ -370,6 +530,31 @@ StringOptionStorage::StringOptionStorage(const StringOption &settings)
         addValue(allowed_[settings.defaultEnumIndex_]);
         commitValues();
     }
+    // Somewhat subtly, this does not update the stored enum index if the
+    // caller has not provided store() or storeVector(), because values()
+    // will be empty in such a case.  This leads to (desired) behavior of
+    // preserving the existing value in the enum index store variable in such
+    // cases.
+    refreshEnumIndexStore();
+}
+
+std::string StringOptionStorage::formatExtraDescription() const
+{
+    std::string result;
+    if (!allowed_.empty())
+    {
+        result.append(": ");
+        ValueList::const_iterator i;
+        for (i = allowed_.begin(); i != allowed_.end(); ++i)
+        {
+            if (i != allowed_.begin())
+            {
+                result.append(", ");
+            }
+            result.append(*i);
+        }
+    }
+    return result;
 }
 
 std::string StringOptionStorage::formatSingleValue(const std::string &value) const
@@ -409,15 +594,27 @@ void StringOptionStorage::convertValue(const std::string &value)
 void StringOptionStorage::refreshValues()
 {
     MyBase::refreshValues();
+    refreshEnumIndexStore();
+}
+
+void StringOptionStorage::refreshEnumIndexStore()
+{
     if (enumIndexStore_ != NULL)
     {
         for (size_t i = 0; i < values().size(); ++i)
         {
-            ValueList::const_iterator match =
-                std::find(allowed_.begin(), allowed_.end(), values()[i]);
-            GMX_ASSERT(match != allowed_.end(),
-                       "Enum value not found (internal error)");
-            enumIndexStore_[i] = static_cast<int>(match - allowed_.begin());
+            if (values()[i].empty())
+            {
+                enumIndexStore_[i] = -1;
+            }
+            else
+            {
+                ValueList::const_iterator match =
+                    std::find(allowed_.begin(), allowed_.end(), values()[i]);
+                GMX_ASSERT(match != allowed_.end(),
+                           "Enum value not found (internal error)");
+                enumIndexStore_[i] = static_cast<int>(match - allowed_.begin());
+            }
         }
     }
 }
@@ -455,9 +652,10 @@ const std::vector<std::string> &StringOptionInfo::allowedValues() const
  * StringOption
  */
 
-AbstractOptionStoragePointer StringOption::createStorage() const
+AbstractOptionStorage *
+StringOption::createStorage(const OptionManagerContainer & /*managers*/) const
 {
-    return AbstractOptionStoragePointer(new StringOptionStorage(*this));
+    return new StringOptionStorage(*this);
 }
 
 } // namespace gmx