File traits.hxx#

namespace bout

Provides access to the Hypre library, handling initialisation and finalisation.

Usage

#include <bout/hyprelib.hxx>

class MyClass { public:

private: HypreLib lib; };

This will then automatically initialise Hypre the first time an object is created, and finalise it when the last object is destroyed.

Copyright 2012 B.D.Dudson, S.Farley, M.V.Umansky, X.Q.Xu

Contact: Ben Dudson, bd512@york.ac.uk

This file is part of BOUT++.

BOUT++ is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

BOUT++ is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with BOUT++. If not, see http://www.gnu.org/licenses/.

Information about the version of BOUT++

The build system will update this file on every commit, which may result in files that include it getting rebuilt. Therefore it should be included in as few places as possible

Information about the version of BOUT++

The build system will update this file at configure-time

SNB model

namespace utils#

Typedefs

template<class T>
using is_Field = std::is_base_of<Field, T>#
template<class T>
using is_Field2D = std::is_base_of<Field2D, T>#
template<class T>
using is_Field3D = std::is_base_of<Field3D, T>#
template<class T>
using is_FieldPerp = std::is_base_of<FieldPerp, T>#
template<class T>
using is_Options = std::is_base_of<Options, T>#
template<class... Ts> EnableIfField = std::enable_if_t<(is_Field_v< Ts > and ...), std::common_type_t< Ts... > >

Enable a function if all the Ts are subclasses of Field, and returns the common type: i.e. Field3D if at least one argument is Field3D, otherwise Field2D if they are all Field2D

This is most useful in two particular cases:

  1. when there are multiple overloads for a function but some only make sense for fields (as opposed to BoutReal, say) or vice-versa, and some overloads should not be used for fields

  2. when a function takes multiple fields and the return type is also a field and must be “big enough”

In other cases, such as a function without overloads that only works for fields, consider using static_assert with is_Field to give a nice compile-time error

Examples

Consider the following template function:

template <class T, class U, class V,
     class ResultType = typename bout::utils::EnableIfField<T, U, V>>
auto where(const T& test, const U& gt0, const V& le0) -> ResultType {
  // function body
}
This function only “appears” if T, U and V are all subclasses of Field. ResultType is the common type of T, U and V. If T and U are both Field2D, ResultType is Field2D if V is Field2D, and Field3D if V is Field3D.

template<class... Ts> EnableIfField2D = std::enable_if_t<(is_Field2D_v< Ts > and ...), std::common_type_t< Ts... > >

Enable a function if all the Ts are subclasses of Field2D, and returns the common type

template<class... Ts> EnableIfField3D = std::enable_if_t<(is_Field3D_v< Ts > and ...), std::common_type_t< Ts... > >

Enable a function if all the Ts are subclasses of Field3D, and returns the common type

template<class... Ts> EnableIfFieldPerp = std::enable_if_t<(is_FieldPerp_v< Ts > and ...), std::common_type_t< Ts... > >

Enable a function if all the Ts are subclasses of FieldPerp, and returns the common type

template<class T>
using EnableIfOptions = std::enable_if_t<std::is_base_of_v<Options, T>>#

Enable a function if T is a subclass of Options.

Variables

template<class T>
constexpr bool is_Field_v = std::is_base_of_v<Field, T>#

True if T is derived from Field, otherwise false

Examples

template <class T>
void print_field(const T& field) {
  static_assert(bout::utils::is_Field_v<T>,
      "print_field only works with Field2Ds, Field3Ds or FieldPerps")
  // implementation
}
template<class T>
constexpr bool is_Field2D_v = std::is_base_of_v<Field2D, T>#

True if T is derived from Field2D, otherwise false.

template<class T>
constexpr bool is_Field3D_v = std::is_base_of_v<Field3D, T>#

True if T is derived from Field3D, otherwise false.

template<class T>
constexpr bool is_FieldPerp_v = std::is_base_of_v<FieldPerp, T>#

True if T is derived from FieldPerp, otherwise false.

template<class T>
constexpr bool is_Options_v = std::is_base_of_v<Options, T>#

True if T is derived from Options, otherwise false.