Skip to content
Permalink
Browse files

Merge pull request #13074 from permcody/gcc_8x

Fix compile error in GCC 8.x series
  • Loading branch information...
friedmud committed Mar 22, 2019
2 parents b7d70b5 + 70b72f8 commit 68416a1cc1a051a97b4aec7aa87a99e4b2c3a8da
@@ -28,6 +28,7 @@
#include <string>
#include <vector>
#include <memory>
#include <type_traits>

// DO NOT USE (Deprecated)
#define MooseSharedPointer std::shared_ptr
@@ -64,6 +65,39 @@
beginIndex_2(__VA_ARGS__), \
beginIndex_1(__VA_ARGS__), \
beginIndex_0(__VA_ARGS__))

/**
* MooseIndex Macro for creating an index type of the right type for loops and other places where
* type matching is important.
* Usage:
*
* Type t;
*
* Container type:
* for (MooseIndex(t) i = 0; i < t.size(); ++i)
*
* POD type:
* for (MooseIndex(t) i = 0; i < t; ++i)
*/
#define MooseIndex(type) decltype(_MooseIndex(type, 0))

// SFINAE templates for type MooseIndex type selection
template <typename T, typename std::enable_if<std::is_integral<T>::value>::type * = nullptr>
typename std::remove_const<T>::type
_MooseIndex(T, int)
{
}

template <typename T>
decltype(((T *)nullptr)->size())
_MooseIndex(T, int)
{
}

template <typename T>
decltype("NOTE: MooseIndex only works with integers and objects with size()!")
_MooseIndex(T, double) = delete;

#ifdef __clang__
#pragma clang diagnostic pop
#endif
@@ -47,15 +47,15 @@ SpatialAverageBase::SpatialAverageBase(const InputParameters & parameters)
// Note: We associate the local variable "i" with nbins and "j" with nvals throughout.

// couple variables initialize vectors
for (auto j = beginIndex(_average); j < _nvals; ++j)
for (MooseIndex(_average) j = 0; j < _nvals; ++j)
{
_values[j] = &coupledValue("variable", j);
_average[j] = &declareVector(getVar("variable", j)->name());
}

// initialize the bin center value vector
_bin_center.resize(_nbins);
for (auto i = beginIndex(_counts); i < _nbins; ++i)
for (MooseIndex(_counts) i = 0; i < _nbins; ++i)
_bin_center[i] = (i + 0.5) * _deltaR;
}

@@ -82,7 +82,7 @@ SpatialAverageBase::execute()
// add the volume contributed by the current quadrature point
if (bin >= 0 && bin < static_cast<int>(_nbins))
{
for (auto j = decltype(_nvals)(0); j < _nvals; ++j)
for (MooseIndex(_nvals) j = 0; j < _nvals; ++j)
(*_average[j])[bin] += (*_values[j])[_qp];

_counts[bin]++;
@@ -95,11 +95,11 @@ SpatialAverageBase::finalize()
{
gatherSum(_counts);

for (auto j = beginIndex(_average); j < _nvals; ++j)
for (MooseIndex(_average) j = 0; j < _nvals; ++j)
{
gatherSum(*_average[j]);

for (auto i = beginIndex(_counts); i < _nbins; ++i)
for (MooseIndex(_counts) i = 0; i < _nbins; ++i)
(*_average[j])[i] =
_counts[i] > 0 ? (*_average[j])[i] / static_cast<Real>(_counts[i]) : _empty_bin_value;
}
@@ -110,11 +110,11 @@ SpatialAverageBase::threadJoin(const UserObject & y)
{
const SpatialAverageBase & uo = static_cast<const SpatialAverageBase &>(y);

for (auto i = beginIndex(_counts); i < _nbins; ++i)
for (MooseIndex(_counts) i = 0; i < _nbins; ++i)
{
_counts[i] += uo._counts[i];

for (auto j = beginIndex(_average); j < _nvals; ++j)
for (MooseIndex(_average) j = 0; j < _nvals; ++j)
(*_average[j])[i] += (*uo._average[j])[i];
}
}
@@ -150,6 +150,38 @@ have +good+ names when using auto!
Do not use `auto` in any kind of function or method declaration
## Index Variables in looping constructs
In keeping with good `auto` practices, it would be really nice if we could use `auto` for
loop indices in places where range loops aren't convenient or possible. Unfortunantly, the most
natural code one would like to write yields a warning with our default compiler flags:
```C++
for (auto i = 0; i < v.size(); ++i) // DON'T DO THIS!
warning: comparison of integers of different signs: 'int' and 'std::__1::vector<int, std::__1::allocator<int> >::size_type' (aka 'unsigned long')
```
Explanation:
This warning stems from the fact that numeric literals in C++ are treated as "signed ints". There
are suffixes that can be applied to literals to force the "correct" type, but are you sure you really
know the correct type? If you are thinking "unsigned int" you are in the majority and unfortunantly also
wrong. The right type for a container is `::size_type (aka 'unsigned long')`. See the error message once
more above.
The ideal solution would be to match the type you are looping over or to, but this is slightly more diffucult
than just using `decltype` due to qualifiers like `const`. In MOOSE we have solved this for you with `MooseIndex`:
```C++
// Looping to a scalar index
for (MooseIndex(n_nodes) i = 0; i < nodes; ++i)
... Do something with index i
// Looping to a container size (where range-for isn't sufficient)
for (MooseIndex(vector) i = 0; i < vector.size(); ++i)
... Do something with index i
```
[](---)
# Lambdas
@@ -287,3 +319,4 @@ class MyClass:
- All function definitions should be in *.C files.
- The only exceptions are for inline functions for speed and templates.
- Thou shall not commit accidental insertion in a std::map by using brackets in a RHS operator unless he/she can prove it can't fail.
- Thou shall use range-based loops or MooseIndex() based loops for iteration
@@ -252,7 +252,7 @@ void
FeatureFloodCount::initialize()
{
// Clear the feature marking maps and region counters and other data structures
for (auto map_num = decltype(_maps_size)(0); map_num < _maps_size; ++map_num)
for (MooseIndex(_maps_size) map_num = 0; map_num < _maps_size; ++map_num)
{
_feature_maps[map_num].clear();
_partial_feature_sets[map_num].clear();
@@ -349,11 +349,11 @@ FeatureFloodCount::execute()
else
{
auto n_nodes = current_elem->n_vertices();
for (auto i = decltype(n_nodes)(0); i < n_nodes; ++i)
for (MooseIndex(n_nodes) i = 0; i < n_nodes; ++i)
{
const Node * current_node = current_elem->get_node(i);

for (auto var_num = beginIndex(_vars); var_num < _vars.size(); ++var_num)
for (MooseIndex(_vars) var_num = 0; var_num < _vars.size(); ++var_num)
flood(current_node, var_num);
}
}
@@ -400,7 +400,7 @@ FeatureFloodCount::communicateAndMerge()
if (is_merging_processor)
recv_buffers.reserve(_app.n_processors());

for (auto i = decltype(_n_vars)(0); i < _n_vars; ++i)
for (MooseIndex(_n_vars) i = 0; i < _n_vars; ++i)
{
serialize(send_buffers[0], i);

@@ -1023,7 +1023,7 @@ FeatureFloodCount::mergeSets()
TIME_SECTION(_merge_timer);

// When working with _distribute_merge_work all of the maps will be empty except for one
for (auto map_num = decltype(_maps_size)(0); map_num < _maps_size; ++map_num)
for (MooseIndex(_maps_size) map_num = 0; map_num < _maps_size; ++map_num)
{
for (auto it1 = _partial_feature_sets[map_num].begin();
it1 != _partial_feature_sets[map_num].end();
@@ -1091,7 +1091,7 @@ FeatureFloodCount::consolidateMergedFeatures(std::vector<std::list<FeatureData>>
// Set the member feature count to zero and start counting the actual features
_feature_count = 0;

for (auto map_num = decltype(_maps_size)(0); map_num < _maps_size; ++map_num)
for (MooseIndex(_maps_size) map_num = 0; map_num < _maps_size; ++map_num)
{
for (auto & feature : _partial_feature_sets[map_num])
{
@@ -1388,7 +1388,7 @@ FeatureFloodCount::expandPointHalos()

// Get the nodes on a current element so that we can add in point neighbors
auto n_nodes = elem->n_vertices();
for (auto i = decltype(n_nodes)(0); i < n_nodes; ++i)
for (MooseIndex(n_nodes) i = 0; i < n_nodes; ++i)
{
const Node * current_node = elem->get_node(i);

@@ -1436,7 +1436,7 @@ FeatureFloodCount::expandEdgeHalos(unsigned int num_layers_to_expand)
{
for (auto & feature : list_ref)
{
for (auto halo_level = decltype(num_layers_to_expand)(0); halo_level < num_layers_to_expand;
for (MooseIndex(num_layers_to_expand) halo_level = 0; halo_level < num_layers_to_expand;
++halo_level)
{
/**
@@ -1493,7 +1493,7 @@ FeatureFloodCount::visitElementalNeighbors(const Elem * elem,
MeshBase & mesh = _mesh.getMesh();

// Loop over all neighbors (at the the same level as the current element)
for (auto i = decltype(elem->n_neighbors())(0); i < elem->n_neighbors(); ++i)
for (MooseIndex(elem->n_neighbors()) i = 0; i < elem->n_neighbors(); ++i)
{
const Elem * neighbor_ancestor = nullptr;
bool topological_neighbor = false;
@@ -1630,7 +1630,7 @@ FeatureFloodCount::appendPeriodicNeighborNodes(FeatureData & feature) const
{
Elem * elem = _mesh.elemPtr(entity);

for (auto node_n = decltype(elem->n_nodes())(0); node_n < elem->n_nodes(); ++node_n)
for (MooseIndex(elem->n_nodes()) node_n = 0; node_n < elem->n_nodes(); ++node_n)
{
auto iters = _periodic_node_map.equal_range(elem->node(node_n));

@@ -2070,7 +2070,7 @@ updateBBoxExtremesHelper(MeshTools::BoundingBox & bbox, const Point & node)
void
updateBBoxExtremesHelper(MeshTools::BoundingBox & bbox, const Elem & elem)
{
for (auto node_n = decltype(elem.n_nodes())(0); node_n < elem.n_nodes(); ++node_n)
for (MooseIndex(elem.n_nodes()) node_n = 0; node_n < elem.n_nodes(); ++node_n)
updateBBoxExtremesHelper(bbox, *(elem.get_node(node_n)));
}

0 comments on commit 68416a1

Please sign in to comment.
You can’t perform that action at this time.