source: src/tests/subrange.c @ 4ab3d68e

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsdeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newwith_gc
Last change on this file since 4ab3d68e was e757af2, checked in by Thierry Delisle <tdelisle@…>, 8 years ago

renamed all tests to lower-case leading character

  • Property mode set to 100644
File size: 2.4 KB
RevLine 
[55ba7339]1// A small context defining the notion of an ordered otype.  (The standard
[51b7345]2// library should probably contain a context for this purpose.)
[e5b96bf]3trait ordered(otype T) {
[51b7345]4    int ?<?(T, T), ?<=?(T, T);
5};
6
[55ba7339]7// A subrange otype resembling an Ada subotype with a base otype and a range
[51b7345]8// constraint.
[55ba7339]9otype subrange(otype base_t | ordered(base_t), base_t low = 0, base_t high = 8) = base_t;
[51b7345]10
[55ba7339]11// Note that subrange() can be applied to floating-point and pointer otypes, not
12// just integral otypes.
13//   This requires a "otype generator" extension to Cforall.  Type generators
14// must accept otype and non-otype parameters, which is beyond what we discussed
[51b7345]15// previously.  Type parameters must be usable in the declaration of
16// subsequent parameters: parameter T is used to declare parameters "low"
17// and "high".
18
19// Example usage:
20subrange(unsigned, 1, 31) day_of_month;
21subrange(char, 'a', 'z')  lcase;
22subrange(int, 0, (rand() & 0xF) ) foo;
23
[55ba7339]24// What sorts of expressions can be used as arguments of otype generators?  Is
[51b7345]25// "subrange(int, 0, rand() & 0xF)" legal?  Probably.  The nearest C equivalent
26// to the "low" and "high" arguments is the array size in a variable-length
27// array declaration, and C allows assignment expressions there.
28
29// Convenient access to subrange bounds, for instance for iteration:
[55ba7339]30forall (otype T, T low, T high)
[51b7345]31T lbound( subrange(T, low, high) v) {
32    return low;
33}
34
[55ba7339]35forall (otype T, T low, T high)
[51b7345]36T hbound( subrange(T, low, high) v) {
37    return high;
38}
39
40// Example usage:
41unsigned lday = lbound(day_of_month);
42
[55ba7339]43// Assignment from the base otype, with bounds checking.  I'll ignore the issue
[51b7345]44// of exception handling here.  Inlining allows the compiler to eliminate
45// bounds checks.
[55ba7339]46forall (otype T | ordered(T), T low, T high)
[51b7345]47inline subrange(T, low, high) ?=?(subrange(T, low, high)* target, T source) {
48    if (low <= source && source <= high) *((T*)target) = source;
49    else abort();
50    return target;
51}
52
[55ba7339]53// Assignment between subranges with a common base otype.  The bounds check
[51b7345]54// compares range bounds so that the compiler can optimize checks away when the
55// ranges are known to overlap.
[55ba7339]56forall (otype T | ordered(T), T t_low, T t_high, T s_low, T s_high)
[51b7345]57inline subrange(T, t_low, t_high) ?=?(subrange(T, t_low, t_high)* target,
58                                      subrange(T, s_low, s_high) source) {
59    if ( (t_low <= s_low || t_low <= source)
60         && (s_high <= t_high || source <= t_high) ) *((T*)target) = source;
61    else abort();
62    return target;
63}
Note: See TracBrowser for help on using the repository browser.