Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add is_quotrem_order #191

Open
gpeterhoff opened this issue Feb 4, 2024 · 2 comments
Open

add is_quotrem_order #191

gpeterhoff opened this issue Feb 4, 2024 · 2 comments

Comments

@gpeterhoff
Copy link

gpeterhoff commented Feb 4, 2024

Problem:
std::Xdiv_t can be implemented as {quot, rem} or {rem, quot} (what a mess). This means that structured binding are not unique:
auto [a, b] = std::div(x, y);
is a quot or rem or is b quot or rem ?
is_quotrem_order.hpp

//	Distributed under the Boost Software License Version 1.0 https://www.boost.org/LICENSE_1_0.txt
//	Copyright Gero Peterhoff

#ifndef BOOST_TYPE_TRAITS_IS_QUOTREM_ORDER_HPP
#define BOOST_TYPE_TRAITS_IS_QUOTREM_ORDER_HPP

#include <boost/type_traits/is_bool.hpp>
#include <type_traits>
#include <cmath>



namespace boost
{
namespace detail
{
template <typename Type>
inline constexpr bool	is_quotrem_order()	noexcept
{
	static_assert(std::is_arithmetic<Type>::value, "invalid type");

	//	std::div need signed integer
	using value_type = typename std::conditional_t
		<
			std::is_floating_point<Type>::value || boost::is_bool<Type>::value,
			int,
			typename std::make_signed<Type>::type
		>;
	using div_type = decltype(std::div(value_type{}, value_type{}));

	constexpr div_type
		div{value_type{0}, value_type{1}};

	return div.quot == value_type{0};
}
}	//	detail



template <typename Type> struct is_quotrem_order : public std::integral_constant
<
	bool,
	detail::is_quotrem_order<Type>()
>	{};


#if !defined(BOOST_NO_CXX17_INLINE_VARIABLES)
template <typename Type> inline constexpr bool is_quotrem_order_v = is_quotrem_order<Type>::value;
#endif
}	//	boost

#endif	//	BOOST_TYPE_TRAITS_IS_QUOTREM_ORDER_HPP
@jzmaddock
Copy link
Collaborator

I think this may be overkill: std::div is constexpr from C++23 only making this solution require C++23 as well, but off the top of my head a neater solution might be:

template <class D>
auto div_to_tuple(const D& d)
{
    return std::make_tuple(d.quot, d.rem);
}

So now you can write:

auto [q,r] = div_to_tuple(std::div(a,b));

and this works from C++11 onwards I think.

@gpeterhoff
Copy link
Author

No. There is std::div. Nothing more. Unfortunately, I can't tell you why the C++ committee is not able to do this in a standardized way, let alone provide std::div for unsigned.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants