My task is to modify Sergiu Dotenco's Well Equidistributed Long-period Linear (WELL) algorithm code to not use boost (not saying boost is bad, but due to some company's policy i have to remove it).
now, Sergiu's WELL is using boost's mpl library, there are quite some logic behind it. So one way is to read up all those, then naturally i would be able to finish the task. The other way is, replacing bit by bit with some best guess.
I'm on the 2nd way to hope this try-and-error approach would be faster. So far I've successfully replaced boost::mpl::if_
and if_c
with std::conditional
, but hit error when try to update IsPowerOfTwo
and Power2Modulo
etc, that's why i'm seeking help there.
Below is the code, how to rewrite it without boost, but only c++17?
/**
* Conditional expression of type (r & (r - 1)) == 0 which allows to check
* whether a number @f$r@f$ is of type @f$2^n@f$.
*/
typedef boost::mpl::equal_to<
boost::mpl::bitand_<
boost::mpl::_,
boost::mpl::minus<boost::mpl::_, boost::mpl::int_<1>
>
>,
boost::mpl::int_<0>
> IsPowerOfTwo;
template<class UIntType, UIntType r>
struct Power2Modulo
{
typedef typename boost::mpl::apply<
IsPowerOfTwo,
boost::mpl::integral_c<UIntType, r>
>::type type;
BOOST_STATIC_ASSERT(type::value);
template<class T>
static T calc(T value)
{
return value & (r - 1);
}
};
If possible, pls give a short example on how to call it? I tried to instantiate IsPowerOfTwo
or Power2Modulo
in main with
Detail::IsPowerOfTwo p0;
or
Detail::Power2Modulo<int, 3> p1;
but got compilation error.
I asked a relevant question before and got some suggestion. However, not familiar to metaprogramming and boost, I don't quite get it.
So, I looked at that library, and created a no-boost fork adapting the WELL pseudo-random-number-generator to pure c++11.
See here on my github: https://github.com/sehe/well-random (the default branch is
no-boost
).What Was Refactored
BOOST_STATIC_ASSERT
toSTATIC_ASSERT
(this becomes obsolete with c++17: http://en.cppreference.com/w/cpp/language/static_assert)BOOST_STATIC_CONSTANT
tostatic constexpr
BOOST_PREVENT_MACRO_SUBSTITUTION
->PREVENT_MACRO_SUBSTITUTION
(trivial macro)BOOST_THROW_EXCEPTION
dropped. NOTE This implies the code cannot be compiled with exception support disabled.All things related to Boost Test
BOOST_CHECK
->CHECK
BOOST_CHECK_EQUAL
->CHECK_EQUAL
BOOST_AUTO_TEST_CASE
- dropped. The test driver ismain
now:boost::ref
->std::ref
(from<functional>
)Boost Range helpers replaced by standard c++ (
boost::size
,boost::end
for arrays)using ulong_long_type = unsigned long long;
Conditional operators
shift
andmod
have been re-implemented with straight-up SFINAE based onstd::enable_if
instead of using MPL meta-programming:became:
Likewise, the Modulo switch (
Power2Modulo
andGenericModulo
) that looked like this:became much simpler with a little bit of c++11 (
constexpr
!) goodness:<boost/cstdint.hpp>
-><cstdint>
(replacing::boost
by::std
foruint_least32_t
anduint32_t
)Well_quoted
type function replaced by an alias template (template<...> using T = ...
see http://en.cppreference.com/w/cpp/language/type_alias ad 2)typedef
s rewritten as type aliases.Full Listing
Live On Coliru
Using C++17, this code becomes way simpler and error messages are friendlier on the eye.
This is a sample implementation of
Power2Modulo
:You can use it like this:
Tested with clang-6 and gcc-8 and VisualC++ (via http://webcompiler.cloudapp.net/).