source: libcfa/src/enum.hfa @ 5f210c0

Last change on this file since 5f210c0 was 5f210c0, checked in by JiadaL <j82liang@…>, 4 months ago

Change enum pos to signed int to avoid underflow; operator on enum will not have range check (but succ and pred still have range check

  • Property mode set to 100644
File size: 2.2 KB
Line 
1#pragma once
2
3#include "iostream.hfa"
4
5forall( E ) trait Bounded {
6        E lowerBound();
7        E upperBound();
8};
9
10forall( E | Bounded( E ) ) trait Serial {
11        int fromInstance( E e );
12        E fromInt_unsafe( int i );
13        E succ_unsafe( E e );
14        E pred_unsafe( E e );
15};
16
17forall( E | Serial( E ) ) {
18        E fromInt( int i );
19        E succ( E e );
20        E pred( E e );
21        int Countof( E e );
22}
23
24// forall( E | Bounded(E) ) trait SafeSerial {
25//       // unsigned fromInstance( E e );
26//       E fromInt_unsafe( unsigned i );
27//       // E succ_unsafe( E e );
28//       //E pred_unsafe( E e );
29
30//       unsigned fromInstance( E e );
31//       E fromInt( unsigned i );
32//       E succ( E e );
33//       E pred( E e );
34// };
35
36forall( E ) trait CfaEnum {
37        const char * label( E e );
38        int posn( E e );
39};
40
41forall( E, V | CfaEnum( E ) ) trait TypedEnum {
42        V value( E e );
43};
44
45// I/O
46
47forall( istype & | istream( istype ), E | CfaEnum( E ) | Serial(E) )
48istype & ?|?( istype &, E & );
49
50forall( ostype & | ostream( ostype ), E | CfaEnum( E ) ) {
51        ostype & ?|?( ostype &, E );
52        OSTYPE_VOID( E );
53}
54
55static inline
56forall( E | Serial(E) | CfaEnum(E) ) {
57        int ?==?( E l, E r ) { return posn( l ) == posn( r ); } // relational operators
58        int ?!=?( E l, E r ) { return posn( l ) != posn( r ); }
59        int ?<?( E l, E r ) { return posn( l ) < posn( r ); }
60        int ?<=?( E l, E r ) { return posn( l ) <= posn( r ); }
61        int ?>?( E l, E r ) { return posn( l ) > posn( r ); }
62        int ?>=?( E l, E r ) { return posn( l ) >= posn( r ); }
63
64        E ++?( E & l ) {                                                                        // increment operators
65                int pos = posn(l);
66                l = fromInt_unsafe(pos+1);
67                return l;
68        }
69
70        E --?( E & l ) {
71                int pos = posn(l);
72                l = fromInt_unsafe(pos-1);
73                return l;
74        }
75
76        E ?+=? ( E & l, one_t ) {
77                int pos = posn(l);
78                l = fromInt_unsafe(pos+1);
79                return l;
80        }
81
82        E ?-=? ( E & l, one_t ) {
83                int pos = posn(l);
84                l = fromInt_unsafe(pos-1);
85                return l;
86        }
87
88        E ?+=? ( E & l, int i ) {
89                int pos = posn(l);
90                l = fromInt_unsafe(pos+i);
91                return fromInt(pos);
92        }
93
94        E ?-=? ( E & l, int i ) {
95                int pos = posn(l);
96                l = fromInt_unsafe(pos-i);
97                return l;
98        }
99
100        E ?++( E & l ) {
101                int pos = posn(l);
102                l = fromInt_unsafe(pos+1);
103                return fromInt_unsafe(pos);
104        }
105
106        E ?--( E & l ) {
107                int pos = posn(l);
108                l = fromInt_unsafe(pos-1);
109                return fromInt_unsafe(pos);
110        }
111}
Note: See TracBrowser for help on using the repository browser.