Skip to content

Commit

Permalink
Cleanup in CONSTEXPR compat
Browse files Browse the repository at this point in the history
  • Loading branch information
hivert committed Jan 11, 2018
1 parent d7c7a8f commit 9afd17f
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 53 deletions.
96 changes: 52 additions & 44 deletions include/perm16.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,31 +28,33 @@
#include "HPCombi-config.h"

#ifdef HPCOMBI_CONSTEXPR_FUN_ARGS
#define CONSTEXPR constexpr
#define CONSTEXPR_CONSTRUCTOR constexpr
#define HPCOMBI_CONSTEXPR constexpr
#define HPCOMBI_CONSTEXPR_CONSTRUCTOR constexpr
#else
#define CONSTEXPR const
#define CONSTEXPR_CONSTRUCTOR
#define HPCOMBI_CONSTEXPR const
#define HPCOMBI_CONSTEXPR_CONSTRUCTOR
#endif


namespace HPCombi {

/// SIMD vector of 16 unsigned bytes
using epu8 = uint8_t __attribute__((vector_size(16)));

///
template <class Function, std::size_t... Indices>
CONSTEXPR epu8 make_epu8_helper(Function f, std::index_sequence<Indices...>) {
template <class Function, std::size_t... Indices> HPCOMBI_CONSTEXPR
epu8 make_epu8_helper(Function f, std::index_sequence<Indices...>) {
return epu8{f(Indices)...};
}

template <class Function> CONSTEXPR epu8 make_epu8(Function f) {
template <class Function> HPCOMBI_CONSTEXPR epu8 make_epu8(Function f) {
return make_epu8_helper(f, std::make_index_sequence<16>{});
}

template <uint8_t c> CONSTEXPR uint8_t constfun(uint8_t ignored) { return c; }
template <uint8_t c> HPCOMBI_CONSTEXPR
uint8_t constfun(uint8_t ignored) { return c; }

template <uint8_t c> CONSTEXPR epu8 make_const_epu8() {
template <uint8_t c> HPCOMBI_CONSTEXPR epu8 make_const_epu8() {
return make_epu8_helper(constfun<c>, std::make_index_sequence<16>{});
}

Expand All @@ -61,31 +63,32 @@ template <uint8_t c> CONSTEXPR epu8 make_const_epu8() {
// forbidden. So we put them here.

/// The image of i by the identity function
static CONSTEXPR uint8_t make_one(uint8_t i) { return i; }
static HPCOMBI_CONSTEXPR
uint8_t make_one(uint8_t i) { return i; }
/// The image of i by the left cycle function
static CONSTEXPR uint8_t make_left_cycle(uint8_t i) { return (i + 15) % 16; }
static HPCOMBI_CONSTEXPR
uint8_t make_left_cycle(uint8_t i) { return (i + 15) % 16; }
/// The image of i by the right cycle function
static CONSTEXPR uint8_t make_right_cycle(uint8_t i) { return (i + 1) % 16; }
static HPCOMBI_CONSTEXPR
uint8_t make_right_cycle(uint8_t i) { return (i + 1) % 16; }
/// The image of i by a left shift filling the hole with a @p 0xff
static CONSTEXPR uint8_t make_left_shift_ff(uint8_t i) {
return i == 15 ? 0xff : i + 1;
}
static HPCOMBI_CONSTEXPR
uint8_t make_left_shift_ff(uint8_t i) { return i == 15 ? 0xff : i + 1; }
/// The image of i by a left shift duplicating the hole
static CONSTEXPR uint8_t make_left_shift(uint8_t i) {
return i == 15 ? 15 : i + 1;
}
static HPCOMBI_CONSTEXPR
uint8_t make_left_shift(uint8_t i) { return i == 15 ? 15 : i + 1; }


// Old Clang doesn't automatically broadcast uint8_t into epu8
// We therefore write there the explicit constants
CONSTEXPR epu8 cst_epu8_0x00 = make_const_epu8<0x00>();
CONSTEXPR epu8 cst_epu8_0x01 = make_const_epu8<0x01>();
CONSTEXPR epu8 cst_epu8_0x02 = make_const_epu8<0x02>();
CONSTEXPR epu8 cst_epu8_0x04 = make_const_epu8<0x04>();
CONSTEXPR epu8 cst_epu8_0x08 = make_const_epu8<0x08>();
CONSTEXPR epu8 cst_epu8_0x0F = make_const_epu8<0x0F>();
CONSTEXPR epu8 cst_epu8_0xF0 = make_const_epu8<0xF0>();
CONSTEXPR epu8 cst_epu8_0xFF = make_const_epu8<0xFF>();
HPCOMBI_CONSTEXPR epu8 cst_epu8_0x00 = make_const_epu8<0x00>();
HPCOMBI_CONSTEXPR epu8 cst_epu8_0x01 = make_const_epu8<0x01>();
HPCOMBI_CONSTEXPR epu8 cst_epu8_0x02 = make_const_epu8<0x02>();
HPCOMBI_CONSTEXPR epu8 cst_epu8_0x04 = make_const_epu8<0x04>();
HPCOMBI_CONSTEXPR epu8 cst_epu8_0x08 = make_const_epu8<0x08>();
HPCOMBI_CONSTEXPR epu8 cst_epu8_0x0F = make_const_epu8<0x0F>();
HPCOMBI_CONSTEXPR epu8 cst_epu8_0xF0 = make_const_epu8<0xF0>();
HPCOMBI_CONSTEXPR epu8 cst_epu8_0xFF = make_const_epu8<0xFF>();

// Forward declaration
struct Perm16;
Expand All @@ -97,13 +100,14 @@ struct Transf16;
*
*/
struct alignas(16) Vect16 {
static CONSTEXPR size_t Size = 16;

static HPCOMBI_CONSTEXPR size_t Size = 16;
epu8 v;

Vect16() = default;
CONSTEXPR_CONSTRUCTOR Vect16(epu8 x) : v(x) {}
HPCOMBI_CONSTEXPR_CONSTRUCTOR Vect16(epu8 x) : v(x) {}
Vect16(std::initializer_list<uint8_t> il, uint8_t def = 0);
CONSTEXPR_CONSTRUCTOR operator epu8() const { return v; }
HPCOMBI_CONSTEXPR_CONSTRUCTOR operator epu8() const { return v; }
Vect16 &operator=(const Vect16 &) = default;
Vect16 &operator=(const epu8 &vv) {
v = vv;
Expand Down Expand Up @@ -227,11 +231,11 @@ struct PTransf16 : public Vect16 {
using vect = Vect16;

PTransf16() = default;
CONSTEXPR_CONSTRUCTOR PTransf16(const vect v) : vect(v) {}
CONSTEXPR_CONSTRUCTOR PTransf16(const epu8 x) : vect(x) {}
HPCOMBI_CONSTEXPR_CONSTRUCTOR PTransf16(const vect v) : vect(v) {}
HPCOMBI_CONSTEXPR_CONSTRUCTOR PTransf16(const epu8 x) : vect(x) {}
PTransf16(std::initializer_list<uint8_t> il);

static CONSTEXPR PTransf16 one() { return make_epu8(make_one); }
static HPCOMBI_CONSTEXPR PTransf16 one() { return make_epu8(make_one); }
PTransf16 inline operator*(const PTransf16 &p) const {
return permuted(p).v | (v == cst_epu8_0xFF); }
};
Expand All @@ -243,14 +247,14 @@ struct PTransf16 : public Vect16 {
struct Transf16 : public PTransf16 {

Transf16() = default;
CONSTEXPR_CONSTRUCTOR Transf16(const vect v) : PTransf16(v) {}
CONSTEXPR_CONSTRUCTOR Transf16(const epu8 x) : PTransf16(x) {}
HPCOMBI_CONSTEXPR_CONSTRUCTOR Transf16(const vect v) : PTransf16(v) {}
HPCOMBI_CONSTEXPR_CONSTRUCTOR Transf16(const epu8 x) : PTransf16(x) {}
Transf16(std::initializer_list<uint8_t> il) : PTransf16(il) {}
explicit Transf16(uint64_t compressed);

explicit operator uint64_t() const;

static CONSTEXPR Transf16 one() { return make_epu8(make_one); }
static HPCOMBI_CONSTEXPR Transf16 one() { return make_epu8(make_one); }
Transf16 inline operator*(const Transf16 &p) const { return permuted(p); }
};

Expand All @@ -261,8 +265,8 @@ struct Transf16 : public PTransf16 {
struct Perm16 : public Transf16 {

Perm16() = default;
CONSTEXPR_CONSTRUCTOR Perm16(const vect v) : Transf16(v) {}
CONSTEXPR_CONSTRUCTOR Perm16(const epu8 x) : Transf16(x) {}
HPCOMBI_CONSTEXPR_CONSTRUCTOR Perm16(const vect v) : Transf16(v) {}
HPCOMBI_CONSTEXPR_CONSTRUCTOR Perm16(const epu8 x) : Transf16(x) {}
Perm16(std::initializer_list<uint8_t> il) : Transf16(il) {}
explicit Perm16(uint64_t compressed) : Transf16(compressed) {}
Perm16 inline operator*(const Perm16 &p) const { return permuted(p); }
Expand Down Expand Up @@ -321,13 +325,16 @@ struct Perm16 : public Transf16 {
// It's not possible to have a static constexpr member of same type as class
// being defined (see https://stackoverflow.com/questions/11928089/)
// therefore we chose to have functions.
static CONSTEXPR Perm16 one() { return make_epu8(make_one); }
static CONSTEXPR Perm16 left_cycle() { return make_epu8(make_left_cycle); }
static CONSTEXPR Perm16 right_cycle() { return make_epu8(make_right_cycle); }
static CONSTEXPR Perm16 left_shift() { return make_epu8(make_left_shift); }
static CONSTEXPR Perm16 left_shift_ff() {
return make_epu8(make_left_shift_ff);
}
static HPCOMBI_CONSTEXPR
Perm16 one() { return make_epu8(make_one); }
static HPCOMBI_CONSTEXPR
Perm16 left_cycle() { return make_epu8(make_left_cycle); }
static HPCOMBI_CONSTEXPR
Perm16 right_cycle() { return make_epu8(make_right_cycle); }
static HPCOMBI_CONSTEXPR
Perm16 left_shift() { return make_epu8(make_left_shift); }
static HPCOMBI_CONSTEXPR
Perm16 left_shift_ff() { return make_epu8(make_left_shift_ff); }

inline static Perm16 elementary_transposition(uint64_t i);
static Perm16 random();
Expand Down Expand Up @@ -359,6 +366,7 @@ static_assert(sizeof(Vect16) == sizeof(Perm16),
static_assert(std::is_trivial<Vect16>(), "Vect16 is not a trivial class !");
static_assert(std::is_trivial<Perm16>(), "Perm16 is not a trivial class !");

const uint64_t prime = 0x9e3779b97f4a7bb9;
} // namespace HPCombi

#include "perm16_impl.hpp"
Expand Down
16 changes: 7 additions & 9 deletions include/perm16_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
namespace HPCombi {

// Definitions since previously *only* declared
CONSTEXPR size_t Vect16::Size;
HPCOMBI_CONSTEXPR size_t Vect16::Size;

/*****************************************************************************/
/** Implementation part for inline functions *********************************/
Expand Down Expand Up @@ -188,8 +188,6 @@ inline bool Vect16::is_permutation(const size_t k) const {
(diff == Size || diff < k);
}

const uint64_t prime = 0x9e3779b97f4a7bb9;

inline Vect16 Vect16::sorted() const {
Vect16 res = *this;
for (auto round : sorting_rounds) {
Expand Down Expand Up @@ -225,12 +223,12 @@ inline PTransf16::PTransf16(std::initializer_list<uint8_t> il) {
v[i] = i;
}

static CONSTEXPR uint8_t hilo_exchng_fun(uint8_t i) {
return i < 8 ? i + 8 : i - 8; }
static CONSTEXPR epu8 hilo_exchng = make_epu8(hilo_exchng_fun);
static CONSTEXPR uint8_t hilo_mask_fun(uint8_t i) {
return i < 8 ? 0x0 : 0xFF; }
static CONSTEXPR epu8 hilo_mask = make_epu8(hilo_mask_fun);
static HPCOMBI_CONSTEXPR
uint8_t hilo_exchng_fun(uint8_t i) { return i < 8 ? i + 8 : i - 8; }
static HPCOMBI_CONSTEXPR epu8 hilo_exchng = make_epu8(hilo_exchng_fun);
static HPCOMBI_CONSTEXPR
uint8_t hilo_mask_fun(uint8_t i) { return i < 8 ? 0x0 : 0xFF; }
static HPCOMBI_CONSTEXPR epu8 hilo_mask = make_epu8(hilo_mask_fun);

inline Transf16::Transf16(uint64_t compressed) {
epu8 res = _mm_set_epi64x(compressed, compressed);
Expand Down

0 comments on commit 9afd17f

Please sign in to comment.