source: src/tests/subrange.c@ a8615fd1

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors deferred_resn demangler enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr no_list persistent-indexer pthread-emulation qualifiedEnum
Last change on this file since a8615fd1 was e757af2, checked in by Thierry Delisle <tdelisle@…>, 9 years ago

renamed all tests to lower-case leading character

  • Property mode set to 100644
File size: 2.4 KB
Line 
1// A small context defining the notion of an ordered otype. (The standard
2// library should probably contain a context for this purpose.)
3trait ordered(otype T) {
4 int ?<?(T, T), ?<=?(T, T);
5};
6
7// A subrange otype resembling an Ada subotype with a base otype and a range
8// constraint.
9otype subrange(otype base_t | ordered(base_t), base_t low = 0, base_t high = 8) = base_t;
10
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
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
24// What sorts of expressions can be used as arguments of otype generators? Is
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:
30forall (otype T, T low, T high)
31T lbound( subrange(T, low, high) v) {
32 return low;
33}
34
35forall (otype T, T low, T high)
36T hbound( subrange(T, low, high) v) {
37 return high;
38}
39
40// Example usage:
41unsigned lday = lbound(day_of_month);
42
43// Assignment from the base otype, with bounds checking. I'll ignore the issue
44// of exception handling here. Inlining allows the compiler to eliminate
45// bounds checks.
46forall (otype T | ordered(T), T low, T high)
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
53// Assignment between subranges with a common base otype. The bounds check
54// compares range bounds so that the compiler can optimize checks away when the
55// ranges are known to overlap.
56forall (otype T | ordered(T), T t_low, T t_high, T s_low, T s_high)
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.