From: Erik Lindahl Date: Wed, 30 Jul 2014 12:46:57 +0000 (+0200) Subject: Fix portability issue with ArrayRef initializer overloading X-Git-Url: http://biod.pnpi.spb.ru/gitweb/?a=commitdiff_plain;h=61ca37ff7b4b8aa9c436818c1e04f1d63ea5dd0d;p=alexxy%2Fgromacs.git Fix portability issue with ArrayRef initializer overloading Some compilers (in particular the Fujitsu compilers that are derived from an earlier version of Clang) will not allow overloading functions where one version uses a pointer to a type, and the other a vector iterator to the same type - likely because they have implemented iterators with pointers. Regardless of what the C++ standard says, we need this working on K computer, so this patch replaces the overloaded initializers with non-member functions that create an ArrayRef or ConstArrayRef either from pointers, an array, or iterators. Change-Id: I4c4e327c869920cc08e3f955e88cb3a5b28c7e87 --- diff --git a/src/gromacs/analysisdata/arraydata.cpp b/src/gromacs/analysisdata/arraydata.cpp index c14fece0ae..55dc204df5 100644 --- a/src/gromacs/analysisdata/arraydata.cpp +++ b/src/gromacs/analysisdata/arraydata.cpp @@ -74,8 +74,8 @@ AbstractAnalysisArrayData::tryGetDataFrameInternal(int index) const = value_.begin() + index * columnCount(); return AnalysisDataFrameRef( AnalysisDataFrameHeader(index, xvalue(index), 0.0), - AnalysisDataValuesRef(begin, begin + columnCount()), - AnalysisDataPointSetInfosRef(&pointSetInfo_, 1)); + constArrayRefFromVector(begin, begin + columnCount()), + constArrayRefFromArray(&pointSetInfo_, 1)); } @@ -184,8 +184,8 @@ AbstractAnalysisArrayData::valuesReady() modules.notifyPointsAdd( AnalysisDataPointSetRef( header, pointSetInfo_, - AnalysisDataValuesRef(valueIter, - valueIter + columnCount()))); + constArrayRefFromVector(valueIter, + valueIter + columnCount()))); modules.notifyFrameFinish(header); } modules.notifyDataFinish(); diff --git a/src/gromacs/analysisdata/dataframe.cpp b/src/gromacs/analysisdata/dataframe.cpp index 12ff2c03c7..cfa09e86a3 100644 --- a/src/gromacs/analysisdata/dataframe.cpp +++ b/src/gromacs/analysisdata/dataframe.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013, by the GROMACS development team, led by + * Copyright (c) 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. @@ -74,8 +74,8 @@ AnalysisDataPointSetRef::AnalysisDataPointSetRef( : header_(header), dataSetIndex_(pointSetInfo.dataSetIndex()), firstColumn_(pointSetInfo.firstColumn()), - values_(&*values.begin() + pointSetInfo.valueOffset(), - pointSetInfo.valueCount()) + values_(constArrayRefFromArray(&*values.begin() + pointSetInfo.valueOffset(), + pointSetInfo.valueCount())) { GMX_ASSERT(header_.isValid(), "Invalid point set reference should not be constructed"); @@ -86,7 +86,7 @@ AnalysisDataPointSetRef::AnalysisDataPointSetRef( const AnalysisDataFrameHeader &header, const std::vector &values) : header_(header), dataSetIndex_(0), firstColumn_(0), - values_(values.begin(), values.end()) + values_(constArrayRefFromVector(values.begin(), values.end())) { GMX_ASSERT(header_.isValid(), "Invalid point set reference should not be constructed"); @@ -166,8 +166,8 @@ AnalysisDataFrameRef::AnalysisDataFrameRef( const AnalysisDataFrameHeader &header, const std::vector &values, const std::vector &pointSets) - : header_(header), values_(values.begin(), values.end()), - pointSets_(pointSets.begin(), pointSets.end()) + : header_(header), values_(constArrayRefFromVector(values.begin(), values.end())), + pointSets_(constArrayRefFromVector(pointSets.begin(), pointSets.end())) { GMX_ASSERT(!pointSets_.empty(), "There must always be a point set"); } @@ -176,7 +176,7 @@ AnalysisDataFrameRef::AnalysisDataFrameRef( AnalysisDataFrameRef::AnalysisDataFrameRef( const AnalysisDataFrameRef &frame, int firstColumn, int columnCount) : header_(frame.header()), - values_(&frame.values_[firstColumn], columnCount), + values_(constArrayRefFromArray(&frame.values_[firstColumn], columnCount)), pointSets_(frame.pointSets_) { // FIXME: This doesn't produce a valid internal state, although it does diff --git a/src/gromacs/analysisdata/datastorage.cpp b/src/gromacs/analysisdata/datastorage.cpp index ec80d9b4c8..57dfea17c7 100644 --- a/src/gromacs/analysisdata/datastorage.cpp +++ b/src/gromacs/analysisdata/datastorage.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013, by the GROMACS development team, led by + * Copyright (c) 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. @@ -635,7 +635,7 @@ AnalysisDataStorageFrameData::addPointSet(int dataSetIndex, int firstColumn, AnalysisDataPointSetInfo pointSetInfo(0, valueCount, dataSetIndex, firstColumn); AnalysisDataPointSetRef pointSet(header(), pointSetInfo, - AnalysisDataValuesRef(begin, end)); + constArrayRefFromVector(begin, end)); storageImpl().modules_->notifyParallelPointsAdd(pointSet); if (storageImpl().shouldNotifyImmediately()) { @@ -684,7 +684,7 @@ AnalysisDataStorageFrameData::pointSet(int index) const "Invalid point set index"); return AnalysisDataPointSetRef( header_, pointSets_[index], - AnalysisDataValuesRef(values_.begin(), values_.end())); + constArrayRefFromVector(values_.begin(), values_.end())); } } // namespace internal diff --git a/src/gromacs/commandline/pargs.cpp b/src/gromacs/commandline/pargs.cpp index e7236740c4..944b3089b5 100644 --- a/src/gromacs/commandline/pargs.cpp +++ b/src/gromacs/commandline/pargs.cpp @@ -798,7 +798,7 @@ gmx_bool parse_common_args(int *argc, char *argv[], unsigned long Flags, if (context != NULL && !(FF(PCA_QUIET))) { gmx::Options options(NULL, NULL); - options.setDescription(gmx::ConstArrayRef(desc, ndesc)); + options.setDescription(gmx::constArrayRefFromArray(desc, ndesc)); for (i = 0; i < nfile; i++) { gmx::filenmToOptions(&options, &fnm[i]); @@ -810,7 +810,7 @@ gmx_bool parse_common_args(int *argc, char *argv[], unsigned long Flags, gmx::CommandLineHelpWriter(options) .setShowDescriptions(true) .setTimeUnitString(output_env_get_time_unit(*oenv)) - .setKnownIssues(gmx::ConstArrayRef(bugs, nbugs)) + .setKnownIssues(gmx::constArrayRefFromArray(bugs, nbugs)) .writeHelp(*context); } } diff --git a/src/gromacs/options/filenameoption.cpp b/src/gromacs/options/filenameoption.cpp index 4bc2810ba9..f5b58f0665 100644 --- a/src/gromacs/options/filenameoption.cpp +++ b/src/gromacs/options/filenameoption.cpp @@ -371,7 +371,7 @@ ConstArrayRef FileNameOptionStorage::extensions() const const FileTypeRegistry ®istry = FileTypeRegistry::instance(); const FileTypeHandler &typeHandler = registry.handlerForType(filetype_, legacyType_); const ExtensionList &extensions = typeHandler.extensions(); - return ConstArrayRef(extensions.begin(), extensions.end()); + return constArrayRefFromVector(extensions.begin(), extensions.end()); } /******************************************************************** diff --git a/src/gromacs/selection/nbsearch.cpp b/src/gromacs/selection/nbsearch.cpp index 06ecbe62a3..24a66ddbda 100644 --- a/src/gromacs/selection/nbsearch.cpp +++ b/src/gromacs/selection/nbsearch.cpp @@ -606,14 +606,14 @@ void AnalysisNeighborhoodPairSearchImpl::startSearch( { if (positions.index_ < 0) { - testPositions_ = ConstArrayRef(positions.x_, positions.count_); + testPositions_ = constArrayRefFromArray(positions.x_, positions.count_); reset(0); } else { // Somewhat of a hack: setup the array such that only the last position // will be used. - testPositions_ = ConstArrayRef(positions.x_, positions.index_ + 1); + testPositions_ = constArrayRefFromArray(positions.x_, positions.index_ + 1); reset(positions.index_); } } diff --git a/src/gromacs/selection/selection.h b/src/gromacs/selection/selection.h index a09167d5a5..2f36c1ecf2 100644 --- a/src/gromacs/selection/selection.h +++ b/src/gromacs/selection/selection.h @@ -333,8 +333,8 @@ class Selection //! Returns atom indices of all atoms in the selection. ConstArrayRef atomIndices() const { - return ConstArrayRef(sel_->rawPositions_.m.mapb.a, - sel_->rawPositions_.m.mapb.nra); + return constArrayRefFromArray(sel_->rawPositions_.m.mapb.a, + sel_->rawPositions_.m.mapb.nra); } //! Number of positions in the selection. int posCount() const { return data().posCount(); } @@ -343,7 +343,7 @@ class Selection //! Returns coordinates for this selection as a continuous array. ConstArrayRef coordinates() const { - return ConstArrayRef(data().rawPositions_.x, posCount()); + return constArrayRefFromArray(data().rawPositions_.x, posCount()); } //! Returns whether velocities are available for this selection. bool hasVelocities() const { return data().rawPositions_.v != NULL; } @@ -355,7 +355,7 @@ class Selection ConstArrayRef velocities() const { GMX_ASSERT(hasVelocities(), "Velocities accessed, but unavailable"); - return ConstArrayRef(data().rawPositions_.v, posCount()); + return constArrayRefFromArray(data().rawPositions_.v, posCount()); } //! Returns whether forces are available for this selection. bool hasForces() const { return sel_->rawPositions_.f != NULL; } @@ -367,7 +367,7 @@ class Selection ConstArrayRef forces() const { GMX_ASSERT(hasForces(), "Forces accessed, but unavailable"); - return ConstArrayRef(data().rawPositions_.f, posCount()); + return constArrayRefFromArray(data().rawPositions_.f, posCount()); } //! Returns masses for this selection as a continuous array. ConstArrayRef masses() const @@ -377,8 +377,8 @@ class Selection // (and thus the masses and charges are fixed). GMX_ASSERT(data().posMass_.size() >= static_cast(posCount()), "Internal inconsistency"); - return ConstArrayRef(data().posMass_.begin(), - data().posMass_.begin() + posCount()); + return constArrayRefFromVector(data().posMass_.begin(), + data().posMass_.begin() + posCount()); } //! Returns charges for this selection as a continuous array. ConstArrayRef charges() const @@ -388,8 +388,8 @@ class Selection // (and thus the masses and charges are fixed). GMX_ASSERT(data().posCharge_.size() >= static_cast(posCount()), "Internal inconsistency"); - return ConstArrayRef(data().posCharge_.begin(), - data().posCharge_.begin() + posCount()); + return constArrayRefFromVector(data().posCharge_.begin(), + data().posCharge_.begin() + posCount()); } /*! \brief * Returns reference IDs for this selection as a continuous array. @@ -398,7 +398,7 @@ class Selection */ ConstArrayRef refIds() const { - return ConstArrayRef(data().rawPositions_.m.refid, posCount()); + return constArrayRefFromArray(data().rawPositions_.m.refid, posCount()); } /*! \brief * Returns mapped IDs for this selection as a continuous array. @@ -407,7 +407,7 @@ class Selection */ ConstArrayRef mappedIds() const { - return ConstArrayRef(data().rawPositions_.m.mapid, posCount()); + return constArrayRefFromArray(data().rawPositions_.m.mapid, posCount()); } //! Returns whether the covered fraction can change between frames. @@ -654,7 +654,7 @@ class SelectionPosition return ConstArrayRef(); } const int first = sel_->rawPositions_.m.mapb.index[i_]; - return ConstArrayRef(&atoms[first], atomCount()); + return constArrayRefFromArray(&atoms[first], atomCount()); } /*! \brief * Returns whether this position is selected in the current frame. diff --git a/src/gromacs/utility/arrayref.h b/src/gromacs/utility/arrayref.h index c02f120ab0..982c712b7d 100644 --- a/src/gromacs/utility/arrayref.h +++ b/src/gromacs/utility/arrayref.h @@ -144,41 +144,15 @@ class ArrayRef * \param[in] end Pointer to the end of a range. * * Passed pointers must remain valid for the lifetime of this object. + * + * \note For clarity, use the non-member function arrayRefFromPointers + * instead. */ ArrayRef(pointer begin, pointer end) : begin_(begin), end_(end) { GMX_ASSERT(end >= begin, "Invalid range"); } - /*! \brief - * Constructs a reference to a particular range in a std::vector. - * - * \param[in] begin Iterator to the beginning of a range. - * \param[in] end Iterator to the end of a range. - * - * The referenced vector must remain valid and not be reallocated for - * the lifetime of this object. - */ - ArrayRef(typename std::vector::iterator begin, - typename std::vector::iterator end) - : begin_((begin != end) ? &*begin : NULL), - end_(begin_+(end-begin)) - { - GMX_ASSERT(end >= begin, "Invalid range"); - } - /*! \brief - * Constructs a reference to an array. - * - * \param[in] begin Pointer to the beginning of the array. - * May be NULL if \p size is zero. - * \param[in] size Number of elements in the array. - * - * Passed pointer must remain valid for the lifetime of this object. - */ - ArrayRef(pointer begin, size_type size) - : begin_(begin), end_(begin + size) - { - } //! \cond // Doxygen 1.8.5 doesn't parse the declaration correctly... /*! \brief @@ -281,6 +255,62 @@ class ArrayRef pointer end_; }; + +/*! \brief + * Constructs a reference to a particular range from two pointers. + * + * \param[in] begin Pointer to the beginning of a range. + * \param[in] end Pointer to the end of a range. + * + * Passed pointers must remain valid for the lifetime of this object. + * + * \related ArrayRef + */ +template +ArrayRef arrayRefFromPointers(T * begin, T * end) +{ + return ArrayRef(begin, end); +} + +/*! \brief + * Constructs a reference to an array + * + * \param[in] begin Pointer to the beginning of the array. + * May be NULL if \p size is zero. + * \param[in] size Number of elements in the array. + * + * Passed pointer must remain valid for the lifetime of this object. + * + * \related ArrayRef + */ +template +ArrayRef arrayRefFromArray(T * begin, size_t size) +{ + return arrayRefFromPointers(begin, begin+size); +} + +/*! \brief + * Constructs a reference to a particular range in a std::vector. + * + * \param[in] begin Iterator to the beginning of a range. + * \param[in] end Iterator to the end of a range. + * + * The referenced vector must remain valid and not be reallocated for + * the lifetime of this object. + * + * \related ArrayRef + */ +template +ArrayRef arrayRefFromVector(typename std::vector::iterator begin, + typename std::vector::iterator end) +{ + T * p_begin = (begin != end) ? &*begin : NULL; + T * p_end = p_begin + (end-begin); + return arrayRefFromPointers(p_begin, p_end); +} + + + /*! \brief * STL-like container for non-mutable interface to a C array (or part of a * std::vector). @@ -354,41 +384,15 @@ class ConstArrayRef * \param[in] end Pointer to the end of a range. * * Passed pointers must remain valid for the lifetime of this object. + * + * \note For clarity, use the non-member function constArrayRefFromPointers + * instead. */ ConstArrayRef(const_pointer begin, const_pointer end) : begin_(begin), end_(end) { GMX_ASSERT(end >= begin, "Invalid range"); } - /*! \brief - * Constructs a reference to a particular range in a std::vector. - * - * \param[in] begin Iterator to the beginning of a range. - * \param[in] end Iterator to the end of a range. - * - * The referenced vector must remain valid and not be reallocated for - * the lifetime of this object. - */ - ConstArrayRef(typename std::vector::const_iterator begin, - typename std::vector::const_iterator end) - : begin_((begin != end) ? &*begin : NULL), - end_(begin_+(end-begin)) - { - GMX_ASSERT(end >= begin, "Invalid range"); - } - /*! \brief - * Constructs a reference to an array. - * - * \param[in] begin Pointer to the beginning of the array. - * May be NULL if \p size is zero. - * \param[in] size Number of elements in the array. - * - * Passed pointer must remain valid for the lifetime of this object. - */ - ConstArrayRef(const_pointer begin, size_type size) - : begin_(begin), end_(begin + size) - { - } //! \cond // Doxygen 1.8.5 doesn't parse the declaration correctly... /*! \brief @@ -465,6 +469,60 @@ class ConstArrayRef const_pointer end_; }; + +/*! \brief + * Constructs a reference to a particular range from two pointers. + * + * \param[in] begin Pointer to the beginning of a range. + * \param[in] end Pointer to the end of a range. + * + * Passed pointers must remain valid for the lifetime of this object. + * + * \related ConstArrayRef + */ +template +ConstArrayRef constArrayRefFromPointers(const T * begin, const T * end) +{ + return ConstArrayRef(begin, end); +} + +/*! \brief + * Constructs a reference to an array. + * + * \param[in] begin Pointer to the beginning of the array. + * May be NULL if \p size is zero. + * \param[in] size Number of elements in the array. + * + * Passed pointer must remain valid for the lifetime of this object. + * + * \related ConstArrayRef + */ +template +ConstArrayRef constArrayRefFromArray(const T * begin, size_t size) +{ + return constArrayRefFromPointers(begin, begin+size); +} + +/*! \brief + * Constructs a reference to a particular range in a std::vector. + * + * \param[in] begin Iterator to the beginning of a range. + * \param[in] end Iterator to the end of a range. + * + * The referenced vector must remain valid and not be reallocated for + * the lifetime of this object. + * + * \related ConstArrayRef + */ +template +ConstArrayRef constArrayRefFromVector(typename std::vector::const_iterator begin, + typename std::vector::const_iterator end) +{ + const T * p_begin = (begin != end) ? &*begin : NULL; + const T * p_end = p_begin + (end-begin); + return constArrayRefFromPointers(p_begin, p_end); +} + /*! \brief * Simple swap method for ArrayRef objects. *