Skip to content

Commit

Permalink
Merge pull request #244 from bluescarni/pr/clang-tidy
Browse files Browse the repository at this point in the history
Adding support for clang-tidy
  • Loading branch information
bluescarni authored Jun 2, 2020
2 parents 9c81368 + 762f087 commit b03bf6b
Show file tree
Hide file tree
Showing 145 changed files with 1,700 additions and 185 deletions.
402 changes: 402 additions & 0 deletions .clang-tidy

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions config.hpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,17 @@

#endif

// Wrapper for the C++17 [[nodiscard]] attribute.
#if MPPP_CPLUSPLUS >= 201703L

#define MPPP_NODISCARD [[nodiscard]]

#else

#define MPPP_NODISCARD

#endif

// C++20 constinit.
#if defined(__cpp_constinit)

Expand Down
2 changes: 2 additions & 0 deletions doc/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ Changelog
New
~~~

- mp++ now builds cleanly with ``clang-tidy``
(`#244 <https://github.com/bluescarni/mppp/pull/244>`__).
- Implement additional three-way comparison functions
for :cpp:class:`~mppp::real`
(`#243 <https://github.com/bluescarni/mppp/pull/243>`__).
Expand Down
41 changes: 27 additions & 14 deletions include/mp++/complex.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,10 @@ class MPPP_DLL_PUBLIC complex
{
// Make friends, for accessing the non-checking prec setting funcs.
template <bool, typename F, typename Arg0, typename... Args>
// NOLINTNEXTLINE(readability-redundant-declaration)
friend complex &detail::mpc_nary_op_impl(::mpfr_prec_t, const F &, complex &, Arg0 &&, Args &&...);
template <bool, typename F, typename Arg0, typename... Args>
// NOLINTNEXTLINE(readability-redundant-declaration)
friend complex detail::mpc_nary_op_return_impl(::mpfr_prec_t, const F &, Arg0 &&, Args &&...);

// Utility function to check the precision upon init.
Expand Down Expand Up @@ -176,9 +178,9 @@ class MPPP_DLL_PUBLIC complex
complex(const complex &);
// Move constructor.
complex(complex &&other) noexcept
: // Shallow copy other.
m_mpc(other.m_mpc)
{
// Shallow copy other.
m_mpc = other.m_mpc;
// Mark the other as moved-from.
other.m_mpc.re->_mpfr_d = nullptr;
}
Expand All @@ -194,6 +196,7 @@ class MPPP_DLL_PUBLIC complex
};
// From real-valued interoperable types + optional precision.
template <typename T, typename... Args>
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init, hicpp-member-init)
explicit complex(gtag, std::true_type, T &&x, const Args &... args)
{
// Init the real part from x + optional explicit precision.
Expand All @@ -217,6 +220,7 @@ class MPPP_DLL_PUBLIC complex
// NOTE: no need for std::forward, as this constructor will involve
// only std::complex or complex128.
template <typename T, typename... Args>
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init, hicpp-member-init)
explicit complex(gtag, std::false_type, const T &c, const Args &... args) : complex(c.real(), c.imag(), args...)
{
}
Expand All @@ -228,6 +232,7 @@ class MPPP_DLL_PUBLIC complex
#else
template <typename T, detail::enable_if_t<is_complex_interoperable<T>::value, int> = 0>
#endif
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init, hicpp-member-init, bugprone-forwarding-reference-overload)
explicit complex(T &&x) : complex(gtag{}, is_rv_complex_interoperable<T>{}, std::forward<T>(x))
{
}
Expand All @@ -237,6 +242,7 @@ class MPPP_DLL_PUBLIC complex
#else
template <typename T, detail::enable_if_t<is_complex_interoperable<T>::value, int> = 0>
#endif
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init, hicpp-member-init)
explicit complex(T &&x, complex_prec_t p) : complex(gtag{}, is_rv_complex_interoperable<T>{}, std::forward<T>(x), p)
{
}
Expand Down Expand Up @@ -268,6 +274,7 @@ class MPPP_DLL_PUBLIC complex
detail::enable_if_t<
detail::conjunction<is_rv_complex_interoperable<T>, is_rv_complex_interoperable<U>>::value, int> = 0>
#endif
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init, hicpp-member-init)
explicit complex(T &&re, U &&im)
{
// NOTE: the precision will be the largest between the
Expand All @@ -283,6 +290,7 @@ class MPPP_DLL_PUBLIC complex
detail::enable_if_t<
detail::conjunction<is_rv_complex_interoperable<T>, is_rv_complex_interoperable<U>>::value, int> = 0>
#endif
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init, hicpp-member-init)
explicit complex(T &&re, U &&im, complex_prec_t p)
{
real_imag_ctor_impl(std::forward<T>(re), std::forward<U>(im), static_cast<::mpfr_prec_t>(p));
Expand All @@ -306,6 +314,7 @@ class MPPP_DLL_PUBLIC complex
#else
template <typename T, detail::enable_if_t<is_string_type<T>::value, int> = 0>
#endif
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init, hicpp-member-init)
explicit complex(const T &s, int base, complex_prec_t p) : complex(stag{}, s, base, static_cast<::mpfr_prec_t>(p))
{
}
Expand All @@ -315,6 +324,7 @@ class MPPP_DLL_PUBLIC complex
#else
template <typename T, detail::enable_if_t<is_string_type<T>::value, int> = 0>
#endif
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init, hicpp-member-init)
explicit complex(const T &s, complex_prec_t p) : complex(s, 10, p)
{
}
Expand Down Expand Up @@ -399,6 +409,7 @@ class MPPP_DLL_PUBLIC complex
#else
template <typename T, detail::enable_if_t<is_complex_interoperable<T>::value, int> = 0>
#endif
// NOLINTNEXTLINE(cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator)
complex &operator=(T &&x)
{
dispatch_generic_assignment(std::forward<T>(x), is_rv_complex_interoperable<T>{});
Expand All @@ -414,7 +425,7 @@ class MPPP_DLL_PUBLIC complex
#endif

// Check validity.
bool is_valid() const noexcept
MPPP_NODISCARD bool is_valid() const noexcept
{
return mpc_realref(&m_mpc)->_mpfr_d != nullptr;
}
Expand Down Expand Up @@ -607,11 +618,11 @@ class MPPP_DLL_PUBLIC complex
#if MPPP_CPLUSPLUS >= 201703L
// Helpers to construct re/im refs.
// They require C++17.
re_cref real_cref() const
[[nodiscard]] re_cref real_cref() const
{
return re_cref{*this};
}
im_cref imag_cref() const
[[nodiscard]] im_cref imag_cref() const
{
return im_cref{*this};
}
Expand All @@ -625,7 +636,7 @@ class MPPP_DLL_PUBLIC complex
}
#endif
// Extract copies of the real/imaginary parts.
std::pair<real, real> get_real_imag() const &;
MPPP_NODISCARD std::pair<real, real> get_real_imag() const &;
// Move out the real/imaginary parts.
std::pair<real, real> get_real_imag() &&
{
Expand All @@ -639,7 +650,7 @@ class MPPP_DLL_PUBLIC complex
}

// Precision getter.
::mpfr_prec_t get_prec() const
MPPP_NODISCARD ::mpfr_prec_t get_prec() const
{
assert(mpfr_get_prec(mpc_realref(&m_mpc)) == mpfr_get_prec(mpc_imagref(&m_mpc)));

Expand Down Expand Up @@ -679,7 +690,7 @@ class MPPP_DLL_PUBLIC complex
complex &prec_round(::mpfr_prec_t);

// mpc_t getters.
const mpc_struct_t *get_mpc_t() const
MPPP_NODISCARD const mpc_struct_t *get_mpc_t() const
{
return &m_mpc;
}
Expand All @@ -689,16 +700,16 @@ class MPPP_DLL_PUBLIC complex
}

// Detect special values.
bool zero_p() const
MPPP_NODISCARD bool zero_p() const
{
return mpfr_zero_p(mpc_realref(&m_mpc)) != 0 && mpfr_zero_p(mpc_imagref(&m_mpc)) != 0;
}
bool is_one() const;
MPPP_NODISCARD bool is_one() const;

private:
// Implementation of the conversion operator.
template <typename T>
T dispatch_conversion(std::true_type) const
MPPP_NODISCARD T dispatch_conversion(std::true_type) const
{
if (std::is_same<T, bool>::value) {
return static_cast<T>(!zero_p());
Expand All @@ -714,7 +725,7 @@ class MPPP_DLL_PUBLIC complex
}
}
template <typename T>
T dispatch_conversion(std::false_type) const
MPPP_NODISCARD T dispatch_conversion(std::false_type) const
{
using value_type = typename T::value_type;

Expand Down Expand Up @@ -801,7 +812,7 @@ class MPPP_DLL_PUBLIC complex
std::integral_constant<int, is_rv_complex_interoperable<T>::value + std::is_same<T, real>::value * 2>{});
}

std::string to_string(int base = 10) const;
MPPP_NODISCARD std::string to_string(int base = 10) const;

private:
template <typename T>
Expand Down Expand Up @@ -903,7 +914,7 @@ namespace detail
template <typename... Args>
using complex_set_t = decltype(std::declval<complex &>().set(std::declval<const Args &>()...));

}
} // namespace detail

#if defined(MPPP_HAVE_CONCEPTS)

Expand Down Expand Up @@ -2975,12 +2986,14 @@ MPPP_DECLARE_COMPLEX_UDL(1024)
template <std::size_t SSize>
inline integer<SSize> &integer<SSize>::operator=(const complex &c)
{
// NOLINTNEXTLINE(cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator)
return *this = static_cast<integer<SSize>>(c);
}

template <std::size_t SSize>
inline rational<SSize> &rational<SSize>::operator=(const complex &c)
{
// NOLINTNEXTLINE(cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator)
return *this = static_cast<rational<SSize>>(c);
}

Expand Down
20 changes: 17 additions & 3 deletions include/mp++/complex128.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,12 @@ namespace mppp
// See also:
// https://gcc.gnu.org/onlinedocs/gcc/Floating-Types.html
#if (!defined(_ARCH_PPC)) || defined(__LONG_DOUBLE_IEEE128__)
// NOTE: not sure about the correct syntax for 'using'+attributes
// here. Let's leave it verbatim like from the quadmath.h header.
// NOLINTNEXTLINE(modernize-use-using)
typedef _Complex float __attribute__((mode(TC))) cplex128;
#else
// NOLINTNEXTLINE(modernize-use-using)
typedef _Complex float __attribute__((mode(KC))) cplex128;
#endif

Expand Down Expand Up @@ -91,6 +95,7 @@ constexpr complex128 conj(const complex128 &);
class MPPP_DLL_PUBLIC complex128
{
public:
// NOLINTNEXTLINE(modernize-use-default-member-init)
cplex128 m_value;

using value_type = real128;
Expand Down Expand Up @@ -183,12 +188,15 @@ class MPPP_DLL_PUBLIC complex128
#else
template <typename T, detail::enable_if_t<is_string_type<T>::value, int> = 0>
#endif
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init, hicpp-member-init)
explicit complex128(const T &s) : complex128(ptag{}, s)
{
}
// Constructor from range of characters.
explicit complex128(const char *, const char *);

~complex128() = default;

// Trivial copy assignment operator.
complex128 &operator=(const complex128 &) = default;
// Trivial move assignment operator.
Expand All @@ -209,6 +217,7 @@ class MPPP_DLL_PUBLIC complex128
#endif
MPPP_CONSTEXPR_14 complex128 &operator=(const T &x)
{
// NOLINTNEXTLINE(cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator)
return *this = complex128{x};
}

Expand All @@ -220,6 +229,7 @@ class MPPP_DLL_PUBLIC complex128
#endif
MPPP_CONSTEXPR_14 complex128 &operator=(const T &c)
{
// NOLINTNEXTLINE(cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator)
return *this = complex128{c};
}
#if defined(MPPP_WITH_MPC)
Expand All @@ -234,15 +244,16 @@ class MPPP_DLL_PUBLIC complex128
#endif
complex128 &operator=(const T &s)
{
// NOLINTNEXTLINE(cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator)
return *this = complex128{s};
}

// Getters for the real/imaginary parts.
constexpr real128 real() const
MPPP_NODISCARD constexpr real128 real() const
{
return real128{__real__ m_value};
}
constexpr real128 imag() const
MPPP_NODISCARD constexpr real128 imag() const
{
return real128{__imag__ m_value};
}
Expand Down Expand Up @@ -372,7 +383,7 @@ class MPPP_DLL_PUBLIC complex128
}

// Conversion to string.
std::string to_string() const;
MPPP_NODISCARD std::string to_string() const;

// Complex absolute value.
complex128 &abs();
Expand Down Expand Up @@ -1211,6 +1222,7 @@ inline complex128 operator"" _icq()
template <std::size_t SSize>
inline integer<SSize> &integer<SSize>::operator=(const complex128 &x)
{
// NOLINTNEXTLINE(cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator)
return *this = static_cast<integer<SSize>>(x);
}

Expand All @@ -1219,13 +1231,15 @@ inline integer<SSize> &integer<SSize>::operator=(const complex128 &x)
template <std::size_t SSize>
inline rational<SSize> &rational<SSize>::operator=(const complex128 &x)
{
// NOLINTNEXTLINE(cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator)
return *this = static_cast<rational<SSize>>(x);
}

// Implementation of real128's assignment
// from complex128.
inline MPPP_CONSTEXPR_14 real128 &real128::operator=(const complex128 &x)
{
// NOLINTNEXTLINE(cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator)
return *this = static_cast<real128>(x);
}

Expand Down
3 changes: 3 additions & 0 deletions include/mp++/detail/gmp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ using mpz_size_t = decltype(std::declval<mpz_struct_t>()._mp_size);

// Simple RAII holder for GMP integers.
struct mpz_raii {
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init, hicpp-member-init)
mpz_raii()
{
::mpz_init(&m_mpz);
Expand All @@ -60,6 +61,7 @@ using mpq_struct_t = std::remove_extent<::mpq_t>::type;

// Simple RAII holder for GMP rationals.
struct mpq_raii {
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init, hicpp-member-init)
mpq_raii()
{
::mpq_init(&m_mpq);
Expand All @@ -80,6 +82,7 @@ using mpf_struct_t = std::remove_extent<::mpf_t>::type;

// Simple RAII holder for GMP floats.
struct mpf_raii {
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init, hicpp-member-init)
explicit mpf_raii(::mp_bitcnt_t prec)
{
::mpf_init2(&m_mpf, prec);
Expand Down
5 changes: 5 additions & 0 deletions include/mp++/detail/integer_literals.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,15 @@ inline
}
}();

#if MPPP_CPLUSPLUS >= 201703L
assert(base == 2 || base == 8 || base == 10 || base == 16);
#endif

// Run the checks on the rest of the literal,
// after we already checked the first 2 digits.
// For bases 2 and 16, we need to have other digits,
// otherwise the literal is malformed.
// NOLINTNEXTLINE(hicpp-multiway-paths-covered)
switch (base) {
case 2:
if (str_length == 2u) {
Expand Down
2 changes: 2 additions & 0 deletions include/mp++/detail/mpfr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ constexpr bool real_prec_check(::mpfr_prec_t p)
struct mpfr_raii {
// A constructor from a precision value, will set the value to NaN.
// No check is performed on the precision.
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init, hicpp-member-init)
explicit mpfr_raii(::mpfr_prec_t prec)
{
::mpfr_init2(&m_mpfr, prec);
Expand All @@ -91,6 +92,7 @@ struct mpfr_raii {
static_assert(std::numeric_limits<long double>::max_digits10 < nl_max<int>() / 4, "Overflow error.");
static_assert(std::numeric_limits<long double>::max_digits10 * 4 < nl_max<::mpfr_prec_t>(), "Overflow error.");
static_assert(std::numeric_limits<long double>::max_digits10 * 4 < nl_max<::mp_bitcnt_t>(), "Overflow error.");
// NOLINTNEXTLINE(bugprone-misplaced-widening-cast)
static_assert(real_prec_check(static_cast<::mpfr_prec_t>(std::numeric_limits<long double>::max_digits10 * 4)),
"The precision required to represent long double is outside the MPFR min/max precision bounds.");

Expand Down
Loading

0 comments on commit b03bf6b

Please sign in to comment.