Skip to content

Decide on a naming scheme for concepts #1407

@reneSchm

Description

@reneSchm

Provide a description of requested documentation changes.

With C++20 we now can make use of concepts, for example as a replacement for some of the ...expr_t = ... and is_expression_valid<...expr_t> (see below for an example). Concepts can be used similar to classes, but it is useful to make them recognizable by their name. To that, we should pick a convention.

See the comments below for ideas for a naming convention. Please vote via 👍 for at least one convention. Feel free to add your own.

The consequences of this choice are trivial, you may have to read/write the option you pick occasionally. So just upvote the ones you think look nicest.

Examples under the ideas refer to our bool is_compartmental_model, std::assignable and std::same_as.


Example: A concept for CompartmentalModel

The point of this example is to show what we are even talking about, and that concepts are a lot shorter, and, after getting used to the new notation, easier to read than the older SFINAE version we already use.

To test for a class being a compartmental model in mio::Simulation, we currently use

template <typename FP, class M>
using eval_right_hand_side_expr_t = ...

template <typename FP, class M>
using get_initial_values_expr_t = ...

template <typename FP, class M>
using is_compartment_model =
    std::integral_constant<bool, (is_expression_valid<eval_right_hand_side_expr_t, FP, M>::value &&
                                  is_expression_valid<get_initial_values_expr_t, FP, M>::value)>;

template <typename FP, class Model>
class Simulation {
    static_assert(is_compartment_model<FP, M>::value, "Template parameter must be a compartment model.");
    ...
};

This is quite long, and I did leave out multiple lines from the definitions of the expr lines. They also clutter up the namespace.
Using concepts, we can instead write

template <class Model, typename FP>
concept CompartmentalModelConcept =
    requires(Model m, Eigen::Ref<const Eigen::VectorX<FP>> pop_y, Eigen::Ref<Eigen::VectorX<FP>> dydt, FP t) {
        { m.get_initial_values() } -> std::convertible_to<Eigen::VectorX<FP>>;
        m.eval_right_hand_side(pop_y, pop_y, t, dydt);
    };

template <typename FP, CompartmentalModelConcept<FP> M>
class Simulation{
    ...
};

Which is a lot shorter, and does effectively the same.

Places where you may see concepts

Templates:

template <CompartmentalModelConcept C>
class Simulation;

Function parameters:

void simulate(CompartmentalModelConcept c);

Other concepts:

template <class Model, typename FP>
concept FlowModelConcept = requires {
    CompartmentalModelConcept<Model, FP>;
};

Metadata

Metadata

Assignees

No one assigned

    Labels

    class::documentationImprovements or additions to documentation

    Type

    Projects

    Status

    Done (Total)

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions