HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

Model of Arithmetic concept for usage as Opaque typedef

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
conceptopaqueusagetypedefformodelarithmetic

Problem

I have a type that models the Arithmetic concept and use it as an opaque typedef (AKA strong typedef, see Note below) in some projects.

I've put the code into its own repository along with some tests and would like some eyes taking a look into it.

Note: for opaque typedef I understand the definition given in N3515.

  • Prior art exist in Boost.Serialization BOOST_STRONG_TYPEDEF, where it seems that the opaque typedefs created model the Arithmetic concept (it is thought to be used for integers) but:



  • This is not clearly stated



  • It doesn't support C++11 features like constexpr, and move semantics



  • It does not inhibit implicit conversions



  • On implicit conversions: I wanted to allow conversions, but prefer them to be explicit. This could be made configurable but I don't think it is worth the trouble.



Some examples of usage:

-
Example 1: disabling implicit conversions

int a{2};
long b{3};
b = a; // works: the implicit conversion is safe

Arithmetic a{2};
Arithmetic b{3};
b = a; // error: implicit assignment requires implicit conversion
b = Arithmetic{a};               // works: explicit construction
b = static_cast>(a);  // works: explicit conversion


-
Example 2: opaque type-defs

struct Tag1 {};
struct Tag2 {};

using Type1 = Arithmetic;
using Type2 = Arithmetic;
Type1 a{2};
Type2 b{3};
b = Type2{a};               // works: explicit construction
b = static_cast(a);  // works: explicit conversion
Type2 c{a};                 // works: explicit construction


arithmetic_type.hpp:

```
#ifndef BOOST_UTILITIES_ARITHMETIC_TYPE_ARITHMETIC_TYPE_
#define BOOST_UTILITIES_ARITHMETIC_TYPE_ARITHMETIC_TYPE_
////////////////////////////////////////////////////////////////////////////////
#include
#include
////////////////////////////////////////////////////////////////////////////////
namespace boost {
////////////////////////////////////////////////////////////////////////////////

/// \name Index types
///@{
/// \brief Implements an int

Solution

Here are some small things you can improve:

  • constexpr inline isn't necessary: constexpr already implies inline.



-
In the following function:

constexpr friend inline Arithmetic operator+(Arithmetic a,
                                             const Arithmetic& b) noexcept {
    return a += b;
}


The friend keyword isn't useful: the only function you are calling is operator+= which is public. This note holds for all your operator@= and for all the operators that do not use private members.

  • operator and operator>= are generally implemented in function of operator



-
The following member should be
constexpr, not const`:

static const bool is_specialized = true;

Code Snippets

constexpr friend inline Arithmetic operator+(Arithmetic a,
                                             const Arithmetic& b) noexcept {
    return a += b;
}
static const bool is_specialized = true;

Context

StackExchange Code Review Q#44663, answer score: 5

Revisions (0)

No revisions yet.