Skip to content

Commit

Permalink
GRIDEDIT-1546 Added concept to check array template parameters satisf…
Browse files Browse the repository at this point in the history
…y required conditions
  • Loading branch information
BillSenior committed Nov 28, 2024
1 parent b5149cf commit 47a4ccd
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 16 deletions.
30 changes: 30 additions & 0 deletions libs/MeshKernel/include/MeshKernel/Definitions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

#pragma once

#include <concepts>
#include <cstdint>
#include <map>
#include <string>
Expand Down Expand Up @@ -112,4 +113,33 @@ namespace meshkernel
/// @brief Get the string representation of the CurvilinearDirection enumeration values.
const std::string& CurvilinearDirectionToString(CurvilinearDirection direction);

/// @brief The concept specifies that the array type must have an access operator returning the array element type or can be converted to one
template <typename ArrayType, typename ResultType>
concept ArrayConstAccessConcept = requires(const ArrayType& array, const size_t i) {
{ array[i] } -> std::convertible_to<ResultType>;
};

/// @brief A concept that specifies that the array must have a size function return the number of elements in the array
template <typename ArrayType>
concept ArraySizeConcept = requires(const ArrayType& array) {
{ array.size() } -> std::same_as<size_t>;
};

/// @brief A concept that specifies that the array must have a begin and end function.
///
/// Would like to also specify the return type here, but span needs some c++23 functionality here.
/// Then change all iterator usage to cbegin and cend returning a const_iterator
/// std::same_as<typename ArrayType::const_iterator>
template <typename ArrayType>
concept ArrayConstIteratorsConcept = requires(const ArrayType& array) {
{ array.begin() };
{ array.end() };
};

/// @brief A concept that specifies all the functionality required to be usable as a constant array of doubles.
template <typename ArrayType>
concept ValidConstDoubleArray = ArrayConstAccessConcept<ArrayType, double> &&
ArrayConstIteratorsConcept<ArrayType> &&
ArraySizeConcept<ArrayType>;

} // namespace meshkernel
13 changes: 7 additions & 6 deletions libs/MeshKernel/include/MeshKernel/MeshTriangulation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#pragma once

#include <array>
#include <functional>
#include <memory>
#include <string>
#include <vector>
Expand All @@ -51,12 +52,12 @@ namespace meshkernel
{
public:
/// @brief Constructor with array of points
template <class PointVector>
template <ValidConstPointArray PointVector>
MeshTriangulation(const PointVector& nodes,
const Projection projection);

/// @brief Constructor with separate arrays of x- and y-coordinates
template <class VectorType>
template <ValidConstDoubleArray VectorType>
MeshTriangulation(const VectorType& xNodes,
const VectorType& yNodes,
const Projection projection);
Expand Down Expand Up @@ -119,7 +120,7 @@ inline meshkernel::Projection meshkernel::MeshTriangulation::GetProjection() con
return m_projection;
}

template <class PointVector>
template <meshkernel::ValidConstPointArray PointVector>
meshkernel::MeshTriangulation::MeshTriangulation(const PointVector& nodes,
const Projection projection)
: m_nodes(nodes.begin(), nodes.end()),
Expand All @@ -133,10 +134,10 @@ meshkernel::MeshTriangulation::MeshTriangulation(const PointVector& nodes,
std::vector<double> xNodes(nodes.size());
std::vector<double> yNodes(nodes.size());

std::transform(nodes.begin(), nodes.begin(), xNodes.begin(),
std::transform(nodes.begin(), nodes.end(), xNodes.begin(),
[](const Point& p)
{ return p.x; });
std::transform(nodes.begin(), nodes.begin(), yNodes.begin(),
std::transform(nodes.begin(), nodes.end(), yNodes.begin(),
[](const Point& p)
{ return p.y; });

Expand All @@ -146,7 +147,7 @@ meshkernel::MeshTriangulation::MeshTriangulation(const PointVector& nodes,
Compute(xNodesSpan, yNodesSpan);
}

template <class VectorType>
template <meshkernel::ValidConstDoubleArray VectorType>
meshkernel::MeshTriangulation::MeshTriangulation(const VectorType& xNodes,
const VectorType& yNodes,
const Projection projection)
Expand Down
6 changes: 3 additions & 3 deletions libs/MeshKernel/include/MeshKernel/Operations.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -578,7 +578,7 @@ namespace meshkernel
/// @param[in] points The point series.
/// @param[in] projection The projection to use.
/// @return The average coordinate.
template <typename PointVector>
template <ValidConstPointArray PointVector>
[[nodiscard]] Point ComputeAverageCoordinate(const PointVector& points, const Projection& projection);

/// @brief Cartesian projection of a point on a segment defined by other two points
Expand Down Expand Up @@ -661,7 +661,7 @@ inline meshkernel::Cartesian3DPoint meshkernel::operator*(const Cartesian3DPoint

namespace meshkernel
{
template <typename PointVector>
template <ValidConstPointArray PointVector>
[[nodiscard]] Point ComputeAverageCoordinate(const PointVector& points, const Projection& projection)
{
size_t validCount = std::ranges::count_if(points, [](const Point& p)
Expand All @@ -675,7 +675,7 @@ namespace meshkernel
if (validCount != points.size())
{
auto iterator = std::ranges::find_if(points, [](const Point& p)
{ return p.IsValid(); });
{ return p.IsValid(); });
firstValidPoint = static_cast<UInt>(iterator - points.begin());
}

Expand Down
6 changes: 6 additions & 0 deletions libs/MeshKernel/include/MeshKernel/Point.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,12 @@ namespace meshkernel
/// @brief Get the delta-x and -y in Cartesian coordinate system
Vector GetDeltaCartesian(const Point& p1, const Point& p2);

/// @brief A concept that specifies all the functionality required to be usable as an array of points.
template <typename ArrayType>
concept ValidConstPointArray = ArrayConstAccessConcept<ArrayType, Point> &&
ArrayConstIteratorsConcept<ArrayType> &&
ArraySizeConcept<ArrayType>;

} // namespace meshkernel

inline void meshkernel::Point::SetInvalid()
Expand Down
14 changes: 8 additions & 6 deletions libs/MeshKernel/include/MeshKernel/SampleInterpolator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,21 +52,23 @@ namespace meshkernel
/// @brief Constructor.
///
/// The VectorType can be any array type of double precision values, e.g. std::vector, std::span.
template <class VectorType>
template <ValidConstDoubleArray VectorType>
SampleInterpolator(const VectorType& xNodes,
const VectorType& yNodes,
const Projection projection)
: m_triangulation(xNodes, yNodes, projection) {}
: m_triangulation(xNodes, yNodes, projection)
{
}

/// @brief Get the number of nodes of size of the sample data.
UInt Size() const;

/// @brief Set sample data
template <class VectorType>
template <ValidConstDoubleArray VectorType>
void SetData(const std::string& name, const VectorType& sampleData);

/// @brief Interpolate the sample data set at the interpolation nodes.
template <class PointVectorType, class ScalarVectorType>
template <ValidConstPointArray PointVectorType, ValidConstDoubleArray ScalarVectorType>
void Interpolate(const std::string& name, const PointVectorType& iterpolationNodes, ScalarVectorType& result) const;

/// @brief Determine if the SampleInterpolator already has this sample set.
Expand Down Expand Up @@ -95,7 +97,7 @@ inline bool meshkernel::SampleInterpolator::Contains(const std::string& name) co
return m_sampleData.contains(name);
}

template <class VectorType>
template <meshkernel::ValidConstDoubleArray VectorType>
void meshkernel::SampleInterpolator::SetData(const std::string& name, const VectorType& sampleData)
{
if (m_triangulation.NumberOfNodes() != sampleData.size())
Expand All @@ -107,7 +109,7 @@ void meshkernel::SampleInterpolator::SetData(const std::string& name, const Vect
m_sampleData[name].assign(sampleData.begin(), sampleData.end());
}

template <class PointVectorType, class ScalarVectorType>
template <meshkernel::ValidConstPointArray PointVectorType, meshkernel::ValidConstDoubleArray ScalarVectorType>
void meshkernel::SampleInterpolator::Interpolate(const std::string& name, const PointVectorType& iterpolationNodes, ScalarVectorType& result) const
{
if (!Contains(name))
Expand Down
1 change: 0 additions & 1 deletion libs/MeshKernel/src/MeshTriangulation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
#include <iostream>
#include <limits>


extern "C"
{
/// @brief Function of the Triangle library
Expand Down

0 comments on commit 47a4ccd

Please sign in to comment.