This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Sophisticated constraint checks


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]