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

Cannot use integers in template parameters due to private data members. #335

Closed
xamidi opened this issue Nov 7, 2022 · 6 comments
Closed
Assignees

Comments

@xamidi
Copy link

xamidi commented Nov 7, 2022

According to README.md:

  • Signed and unsigned versions of uintwide_t should behave as closely as possible to the behaviors of signed and unsigned versions of built-in int.

So I tried to use math::wide_integer::uint256_t as a template parameter, but it failed with an error

'math::wide_integer::uintwide_t<256, unsigned int>' is not a valid type for a template non-type parameter because it is not structural

Fix:

This seems to be caused by the existence of non-public data members.
In math/wide_integer/uintwide_t.h I replaced all private: by public:, and now it works.

Code example:

#include <cstdint>
#include <iostream>
#include "wide-integer/uintwide_t.h"
template<typename UInt, uint32_t B = 8 * sizeof(UInt), UInt MAX = -UInt(1)> void f(uint32_t n) {
	std::cout << B << "-bit ; MAX = " << MAX << ", n = " << UInt(n) << std::endl;
}
int main() {
	f<math::wide_integer::uint256_t>(42); // prints "256-bit ; MAX = 115792089237316195423570985008687907853269984665640564039457584007913129639935, n = 42"
}

Apart from that, great work! sizeof(UInt) and -UInt(1) wouldn't even work with the types of Boost.Multiprecision, and UInt(-1) refused to be constexpr. All these things work fine with uintwide_t.

@ckormanyos
Copy link
Owner

... tried to use math::wide_integer::uint256_t as a template parameter, but it failed with an error ...

... the existence of non-public data members

Thank you for your query. I must admit, I have never tried this exact kind of templatization. Please allow me to take a look at a few options regarding compatibility and get back to your query shortly.

I would not immediately want to make the private data members public, but we might consider doing this with a new, specific compiler switch.

Anyway, please allow me to investigate your query a bit. i'll get back with suggestions...

Kind regards, Chris

@ckormanyos ckormanyos self-assigned this Nov 7, 2022
@ckormanyos
Copy link
Owner

ckormanyos commented Nov 8, 2022

Proposed solution:

#define WIDE_INTEGER_DISABLE_PRIVATE_CLASS_DATA_MEMBERS

This optional macro can be used to disable uintwide_t's private data members and make them public. This allows the uintwide_t class to be used as a structured class object, such as is needed for constant-valued template parameters in the sense of C++20's constexpr-ness.

Making private data members public is unusual for some designs so the default value is WIDE_INTEGER_DISABLE_PRIVATE_CLASS_DATA_MEMBERS disabled and uintwide_t's data members remain private.

@ckormanyos
Copy link
Owner

The repair is cycling in CI.

Cc: @xamidi

@ckormanyos
Copy link
Owner

Hello @xamidi this is now fixed by #336, see change set b3f4aac

Please use either the command line switch when callinng the compiler:

-DWIDE_INTEGER_DISABLE_PRIVATE_CLASS_DATA_MEMBERS

or

#define WIDE_INTEGER_DISABLE_PRIVATE_CLASS_DATA_MEMBERS

above the inclusion of the uintwide_t.h header file.

@xamidi
Copy link
Author

xamidi commented Nov 8, 2022

Thank you for the quick fix. I switched to the original file already, and all seems good. :)

@xamidi xamidi closed this as completed Nov 8, 2022
@ckormanyos
Copy link
Owner

Thank you for the quick fix. I switched to the original file already, and all seems good.

Great! Thank you @xamidi for raising this interesting issue. Glad it works.
If you encounter anything else or have future ideas, please feel free to stop by.

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

No branches or pull requests

2 participants