This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: Sophisticated constraint checks
- From: Jonathan Wakely <cow at compsoc dot man dot ac dot uk>
- To: "Stephen M. Webb" <stephenw at xandros dot com>
- Cc: libstdc++ <libstdc++ at gcc dot gnu dot org>
- Date: Fri, 4 Mar 2005 15:21:48 +0000
- Subject: Re: Sophisticated constraint checks
- References: <200503031441.51442.stephenw@xandros.com>
On Thu, Mar 03, 2005 at 02:41:51PM -0500, Stephen M. Webb wrote:
> I'm beavering away trying to implement the TR1 [5.1] random stuff and I need
> to add a number of constraint checks. I'm using concept requirements where
> possible and __enable_if<> where I need to constrain a templated type based
> on a type trait, but I need more.
>
> First, some functions have strict constraints on input domain at runtime,
> which to me says throw an exception but TR1 seems to forbid this. Is using
> _GLIBCXX_DEBUG_ASSERT() to raise an assertion only in debug mode really the
> best that can be done?
I agree with Chris, if the programmer braks the prerequisites of the
function they have asked for trouble. Unless the TR specifically says a
diagnostic is required then I think _GLIBCXX_DEBUG_ASSERT is the right
thing to do.
> Second, a number of templates have integer-valued parameters that have
> compile-time constraints (for example, class discard_block<typename, int p,
> int r> has constraints 0 <= r <= p). I can either do something fancy with
> __enable_if<>, which will emit a confusing message to the unwary, or invent
> something of my own and leave it in the random header (not "a" random header,
> that would be wrong). Better yet, perhaps there is already something
> available in the library that I've missed?
>
> Which, in your esteemed collective opinion, would be the best way to constrain
> these template parameters?
I'm not qualified to speak for the esteemed collective, but this might be
simplest (a variation on BOOST_STATIC_ASSERT):
template <bool> struct _ConstraintCheck;
template <> struct _ConstraintCheck<true> { typedef void type; };
template <typename T, int p, int r>
class discard_block
{
typedef typename _ConstraintCheck< 0 <= r && r <= p>::type _ConstraintCheck;
// ...
};
Or something like this is pretty clear, but not re-usable, and the extra
"divide by zero" and "not integer constant" noise in the diagnostic might
confuse some people more than it helps:
template <typename T, int p, int r>
class discard_block
{
// constraints 0 <= r <= p
enum { _Require_r_not_less_than_zero = (1/(0<=r)) };
enum { _Require_r_not_greater_than_p = (1/(r<=p)) };
};
jon
--
"There are perhaps 5% of the population that simply *can't* think.
There are another 5% who *can*, and *do*.
The remaining 90% *can* think, but *don't*."
- R. A. Heinlein