//****************************************************************************// // Copyright (C) 2016-2018 Florent Hivert <Florent.Hivert@lri.fr>, // // // // Distributed under the terms of the GNU General Public License (GPL) // // // // This code 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 // // General Public License for more details. // // // // The full text of the GPL is available at: // // // // http://www.gnu.org/licenses/ // //****************************************************************************//
inline HPCOMBI_CONSTEXPR TPU operator()(type_elem c) const { return make_helper(ConstFun<type_elem>(c),
std::make_index_sequence<size>{});
} // explicit overloading for int constants inline HPCOMBI_CONSTEXPR TPU operator()(int c) const { returnoperator()(uint8_t(c));
} inline HPCOMBI_CONSTEXPR TPU operator()(size_t c) const { returnoperator()(uint8_t(c));
}
};
// The following functions should be constexpr lambdas writen directly in // their corresponding methods. However until C++17, constexpr lambda are // forbidden. So we put them here. /// The image of i by the identity function
HPCOMBI_CONSTEXPR uint8_t id_fun(uint8_t i) { return i; } /// The image of i by the left cycle function
HPCOMBI_CONSTEXPR uint8_t left_cycle_fun(uint8_t i) { return (i + 15) % 16; } /// The image of i by the right cycle function
HPCOMBI_CONSTEXPR
uint8_t right_cycle_fun(uint8_t i) { return (i + 1) % 16; } /// The image of i by a left shift duplicating the hole
HPCOMBI_CONSTEXPR
uint8_t left_dup_fun(uint8_t i) { return i == 15 ? 15 : i + 1; } /// The image of i by a right shift duplicating the hole
HPCOMBI_CONSTEXPR
uint8_t right_dup_fun(uint8_t i) { return i == 0 ? 0 : i - 1; } /// The complement of i to 15
HPCOMBI_CONSTEXPR
uint8_t complement_fun(uint8_t i) { return15 - i; }
HPCOMBI_CONSTEXPR uint8_t popcount4_fun(uint8_t i) { return ((i & 1) != 0 ? 1 : 0)
+ ((i & 2) != 0 ? 1 : 0)
+ ((i & 4) != 0 ? 1 : 0)
+ ((i & 8) != 0 ? 1 : 0);
}
} // Anonymous namespace
/// Factory object for various SIMD constants in particular constexpr
TPUBuild<epu8> Epu8;
/// The indentity #HPCombi::epu8
HPCOMBI_CONSTEXPR epu8 epu8id = Epu8(id_fun); /// The reverted identity #HPCombi::epu8
HPCOMBI_CONSTEXPR epu8 epu8rev = Epu8(complement_fun); /// Left cycle #HPCombi::epu8 permutation
HPCOMBI_CONSTEXPR epu8 left_cycle = Epu8(left_cycle_fun); /// Right cycle #HPCombi::epu8 permutation
HPCOMBI_CONSTEXPR epu8 right_cycle = Epu8(right_cycle_fun); /// Left shift #HPCombi::epu8, duplicating the rightmost entry
HPCOMBI_CONSTEXPR epu8 left_dup = Epu8(left_dup_fun); /// Right shift #HPCombi::epu8, duplicating the leftmost entry
HPCOMBI_CONSTEXPR epu8 right_dup = Epu8(right_dup_fun); /// Popcount #HPCombi::epu8: the ith entry contains the number of bits set in i
HPCOMBI_CONSTEXPR epu8 popcount4 = Epu8(popcount4_fun);
/** Cast a #HPCombi::epu8 to a c++ \c std::array * *Thisisusuallyfasterforalgorithmusingalotofindexedacces.
*/ inline TPUBuild<epu8>::array &as_array(epu8 &v) { returnreinterpret_cast<typename TPUBuild<epu8>::array &>(v);
} /** Cast a constant #HPCombi::epu8 to a C++ \c std::array * *Thisisusuallyfasterforalgorithmusingalotofindexedacces.
*/ inlineconst TPUBuild<epu8>::array &as_array(const epu8 &v) { returnreinterpret_cast<consttypename TPUBuild<epu8>::array &>(v);
} /** Cast a C++ \c std::array to a #HPCombi::epu8 */ // Passing the argument by reference triggers a segfault in gcc // Since vector types doesn't belongs to the standard, I didn't manage // to know if I'm using undefined behavior here. inline epu8 from_array(TPUBuild<epu8>::array a) { returnreinterpret_cast<const epu8 &>(a);
}
/** Cast a #HPCombi::epu8 to a c++ #HPCombi::VectGeneric * *Thisisusuallyfasterforalgorithmusingalotofindexedacces.
*/ inline VectGeneric<16> &as_VectGeneric(epu8 &v) { returnreinterpret_cast<VectGeneric<16> &>(as_array(v));
}
/** Cast a #HPCombi::epu8 to a c++ #HPCombi::VectGeneric * *Thisisusuallyfasterforalgorithmusingalotofindexedacces.
*/ inlineconst VectGeneric<16> &as_VectGeneric(const epu8 &v) { returnreinterpret_cast<const VectGeneric<16> &>(as_array(v));
}
/** Test whether all the entries of a #HPCombi::epu8 are zero */ inlinebool is_all_zero(epu8 a) { return _mm_testz_si128(a, a); } /** Test whether all the entries of a #HPCombi::epu8 are one */ inlinebool is_all_one(epu8 a) { return _mm_testc_si128(a, Epu8(0xFF)); }
/** Equality of #HPCombi::epu8 */ inlinebool equal(epu8 a, epu8 b) { return is_all_zero(_mm_xor_si128(a, b)); } /** Non equality of #HPCombi::epu8 */ inlinebool not_equal(epu8 a, epu8 b) { returnnot equal(a, b); }
/** Permuting a #HPCombi::epu8 */ inline epu8 permuted(epu8 a, epu8 b) { return _mm_shuffle_epi8(a, b); } /** Left shifted of a #HPCombi::epu8 inserting a 0 *@warningweusetheconventionthatthe0entryisontheleft!
*/ inline epu8 shifted_right(epu8 a) { return _mm_bslli_si128(a, 1); } /** Right shifted of a #HPCombi::epu8 inserting a 0 *@warningweusetheconventionthatthe0entryisontheleft!
*/ inline epu8 shifted_left(epu8 a) { return _mm_bsrli_si128(a, 1); } /** Reverting a #HPCombi::epu8 */ inline epu8 reverted(epu8 a) { return permuted(a, epu8rev); }
/** Vector min between two #HPCombi::epu8 0 */ inline epu8 min(epu8 a, epu8 b) { return _mm_min_epu8(a, b); } /** Vector max between two #HPCombi::epu8 0 */ inline epu8 max(epu8 a, epu8 b) { return _mm_max_epu8(a, b); }
/** Testing if a #HPCombi::epu8 is sorted */ inlinebool is_sorted(epu8 a); /** Return a sorted #HPCombi::epu8 *@details *@parAlgorithm: *Usesthe9stagessortingnetwork#sorting_rounds
*/ inline epu8 sorted(epu8 a); /** Return a #HPCombi::epu8 with the two half sorted *@details *@parAlgorithm:Usesa6stagessortingnetwork#sorting_rounds8
*/ inline epu8 sorted8(epu8 a); /** Return a reverse sorted #HPCombi::epu8 *@details *@parAlgorithm: *Usesthe9stagessortingnetwork#sorting_rounds
*/ inline epu8 revsorted(epu8 a); /** Return a #HPCombi::epu8 with the two half reverse sorted *@details *@parAlgorithm:Usesa6stagessortingnetwork#sorting_rounds8
*/ inline epu8 revsorted8(epu8 a);
/** Sort \c this and return the sorting permutation *@details *@parAlgorithm:Usesa9stagessortingnetwork#sorting_rounds8
*/ inline epu8 sort_perm(epu8 & a); /** Sort \c this and return the sorting permutation *@details *@parAlgorithm:Usesa9stagessortingnetwork#sorting_rounds8
*/ inline epu8 sort8_perm(epu8 & a);
/** Find if a vector is a permutation of one other *@details *@parama,b:two#HPCombi::epu8 *@returnsa#HPCombi::epu8 *Foreach@f$0\leqi<16@f$,\cres[i]isthepositionin\caof\cb[i] if\cb[i]appearsexactlyoncein\ca,orundefinedifnot.
*/ inline epu8 permutation_of(epu8 a, epu8 b);
/** A prime number good for hashing */ const uint64_t prime = 0x9e3779b97f4a7bb9;
/** A random #HPCombi::epu8 *@details *@parambnd:theupperboundforthevalueoftheentries *@returnsarandom#HPCombi::epu8withvalueintheinterval *@f$[0,1,2,...,bnd-1]@f$.
*/ inline epu8 random_epu8(uint16_t bnd);
/** Remove duplicates in a sorted #HPCombi::epu8 *@details *@parama:supposedtobesorted *@paramrepl:thevaluereplacingtheduplicateentries(defaultto0) *@returnawhererepeatedoccurencesofentriesarereplacedby\crepl
*/ inline epu8 remove_dups(epu8 a, uint8_t repl = 0);
/** Lexicographic comparison between two #HPCombi::epu8 */ inlinebool less(epu8 a, epu8 b); /** Partial lexicographic comparison between two #HPCombi::epu8 *@parama,b:thevectorstocompare *@paramk:theboundforthelexicographiccomparison *@returnapositive,negativeorzerochardependingontheresult
*/ inlinechar less_partial(epu8 a, epu8 b, int k);
/** return the index of the first zero entry or 16 if there are none *Onlyindexsmallerthanboundaretakenintoaccount.
*/ inline uint64_t first_zero(epu8 v, int bnd); /** return the index of the last zero entry or 16 if there are none *Onlyindexsmallerthanboundaretakenintoaccount.
*/ inline uint64_t last_zero(epu8 v, int bnd); /** return the index of the first non zero entry or 16 if there are none *Onlyindexsmallerthanboundaretakenintoaccount.
*/ inline uint64_t first_non_zero(epu8 v, int bnd); /** return the index of the last non zero entry or 16 if there are none *Onlyindexsmallerthanboundaretakenintoaccount.
*/ inline uint64_t last_non_zero(epu8 v, int bnd);
/** a vector popcount function
*/ inline epu8 popcount16(epu8 v);
/** Test for partial transformation *@details *@returnswhether\cvisapartialtransformation. *@paramvthevectortotest *@paramkthesizeof\c*this(default16) * *Pointswherethefunctionisundefinedaremappedto\c0xff.If\c*this *isatranformationof@f$0\dotsn-1@f$for@f$n<16@f$,itshouldbecompleted *toatransformationof@f$0\dots15@f$byaddingfixedpoints.Thatisthe *values@f$i\geqn@f$shouldbemappedtothemself. *@parExample: *Thepartialtranformation *@f$\begin{matrix}012345\\205..4\end{matrix}@f$ *isencodedbythearray{2,0,5,0xff,0xff,4,6,7,8,9,10,11,12,13,14,15}
*/ inlinebool is_partial_transformation(epu8 v, const size_t k = 16);
/** Test for transformation *@details *@returnswhether\c*thisisatransformation. *@paramvthevectortotest *@paramkthesizeof\c*this(default16) * *If\c*thisisatranformationof@f$0\dotsn-1@f$for@f$n<16@f$, *itshouldbecompletedtoatransformationof@f$0\dots15@f$ *byaddingfixedpoints.Thatisthevalues@f$i\geqn@f$shouldbe *mappedtothemself. *@parExample: *Thetranformation *@f$\begin{matrix}012345\\205214\end{matrix}@f$ *isencodedbythearray{2,0,5,2,1,4,6,7,8,9,10,11,12,13,14,15}
*/ inlinebool is_transformation(epu8 v, const size_t k = 16);
/** Test for partial permutations *@details *@returnswhether\c*thisisapartialpermutation. *@paramvthevectortotest *@paramkthesizeof\c*this(default16) * *Pointswherethefunctionisundefinedaremappedto\c0xff. *If\c*thisisapartialpermutationof@f$0\dotsn-1@f$for@f$n<16@f$, *itshouldbecompletedtoapartialpermutationof@f$0\dots15@f$ *byaddingfixedpoints.Thatisthevalues@f$i\geqn@f$shouldbe *mappedtothemself. *@parExample: *Thepermutation *@f$\begin{matrix}012345\\205..4\end{matrix}@f$ *isencodedbythearray{2,0,5,0xFF,0xFF,4,6,7,8,9,10,11,12,13,14,15}
*/ inlinebool is_partial_permutation(epu8 v, const size_t k = 16);
/** Test for permutations *@details *@returnswhether\c*thisisapermutation. *@paramvthevectortotest *@paramkthesizeof\c*this(default16) * *If\c*thisisapermutationof@f$0\dotsn-1@f$for@f$n<16@f$, *itshouldbecompletedtoapermutationof@f$0\dots15@f$ *byaddingfixedpoints.Thatisthevalues@f$i\geqn@f$shouldbe *mappedtothemself. *@parExample: *Thepermutation *@f$\begin{matrix}012345\\205314\end{matrix}@f$ *isencodedbythearray{2,0,5,3,1,4,6,7,8,9,10,11,12,13,14,15}
*/ inlinebool is_permutation(epu8 v, const size_t k = 16);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.