generic_iterators  1.0.0
Demonstration of implementing and using type safe generic iterators in pure, standard C
maybe.h File Reference

Utilities to define and use a Maybe type. More...

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define Maybe(T)   Maybe##T
 Convenience macro to get the type of the Maybe defined with a certain type. More...
 
#define DefineMaybe(T)
 Define a Maybe<T> type. More...
 
#define Just(v, T)   ((Maybe(T)){.tag = MaybeTag_Just, .val = (v)})
 Wrap a Just value into a Maybe(T). More...
 
#define Nothing(T)   ((Maybe(T)){0})
 Wrap a Nothing value into a Maybe(T). More...
 
#define is_nothing(x)   ((x).tag == MaybeTag_Nothing)
 Check if the given Maybe type is tagged with Nothing. More...
 
#define is_just(x)   ((x).tag == MaybeTag_Just)
 Check if the given Maybe type is tagged with Just. More...
 
#define from_just(x, T)   T##_from_just(x)
 Extract the Just value from given Maybe(T). More...
 
#define from_just_(x)   (x).val
 "Unsafe" version of from_just(x, T). More...
 

Enumerations

enum  MaybeTag { MaybeTag_Nothing = 0 , MaybeTag_Just }
 

Detailed Description

Utilities to define and use a Maybe type.

Note
The Maybe struct members must not be accessed manually unless you know exactly what you're doing. Use from_just or from_just_ after is_just/is_nothing instead.

Macro Definition Documentation

◆ DefineMaybe

#define DefineMaybe (   T)
Value:
typedef struct \
{ \
MaybeTag tag; \
/* Don't access this member manually */ \
T val; \
} Maybe(T); \
static inline T T##_from_just(Maybe(T) maybex) \
{ \
if (is_just(maybex)) { \
return maybex.val; \
} else { \
fputs("Attempted to extract Just value from Nothing", stderr); \
abort(); \
} \
}
#define is_just(x)
Check if the given Maybe type is tagged with Just.
Definition: maybe.h:123
#define Maybe(T)
Convenience macro to get the type of the Maybe defined with a certain type.
Definition: maybe.h:40

Define a Maybe<T> type.

Example

DefineMaybe(int) // Defines a Maybe(int) type as well as its corresponding functions
#define DefineMaybe(T)
Define a Maybe<T> type.
Definition: maybe.h:57
Parameters
TThe type of value this Maybe will hold. Must be alphanumeric.
Note
If T is a pointer, it needs to be typedef-ed into a type that does not contain the *. Only alphanumerics.
This should not be delimited by a semicolon.

◆ from_just

#define from_just (   x,
 
)    T##_from_just(x)

Extract the Just value from given Maybe(T).

Parameters
xThe Maybe type to extract the value from.
TThe type of value the Maybe will hold. Must be alphanumeric.
Returns
Just value of type corresponding to the given Maybe(T) if it's not Nothing.
Note
If T is a pointer, it needs to be typedef-ed into a type that does not contain the *. Only alphanumerics.
Aborts the program if given Maybe(T) struct was tagged with Nothing.

◆ from_just_

#define from_just_ (   x)    (x).val

"Unsafe" version of from_just(x, T).

Parameters
xThe Maybe type to extract the value from.
Returns
Just value of type corresponding to the given Maybe struct.
Note
This does not check whether the Maybe struct actually has a value and hence should only be used when the caller is sure that the Maybe contains a Just value. Otherwise the behavior is undefined.

◆ is_just

#define is_just (   x)    ((x).tag == MaybeTag_Just)

Check if the given Maybe type is tagged with Just.

Parameters
xThe Maybe(T) struct to check against.

◆ is_nothing

#define is_nothing (   x)    ((x).tag == MaybeTag_Nothing)

Check if the given Maybe type is tagged with Nothing.

Parameters
xThe Maybe(T) struct to check against.

◆ Just

#define Just (   v,
 
)    ((Maybe(T)){.tag = MaybeTag_Just, .val = (v)})

Wrap a Just value into a Maybe(T).

Example

Maybe(int) const x = Just(42, int); // Initializes a Maybe(int) with the value 42
#define Just(v, T)
Wrap a Just value into a Maybe(T).
Definition: maybe.h:91
Parameters
vThe concrete value to wrap in Just (must be of the correct type).
TThe type of value the Maybe will hold. Must be alphanumeric.
Note
If T is a pointer, it needs to be typedef-ed into a type that does not contain the *. Only alphanumerics.
The value is simply assigned to the Maybe(T) struct. No implicit copying is done.

◆ Maybe

#define Maybe (   T)    Maybe##T

Convenience macro to get the type of the Maybe defined with a certain type.

Example

Maybe(int) const x = {0}; // Uses the maybe type defined in the previous line
Parameters
TThe type of value the Maybe struct will contain. Must be the same type name passed to DefineMaybe(T).
Note
If T is a pointer, it needs to be typedef-ed into a type that does not contain the *. Only alphanumerics.

◆ Nothing

#define Nothing (   T)    ((Maybe(T)){0})

Wrap a Nothing value into a Maybe(T).

Example

Maybe(int) const x = Nothing(int); // Initializes a Maybe(int) with no value
#define Nothing(T)
Wrap a Nothing value into a Maybe(T).
Definition: maybe.h:108
Parameters
TThe type of value the Maybe will hold. Must be alphanumeric.
Note
If T is a pointer, it needs to be typedef-ed into a type that does not contain the *. Only alphanumerics.

Enumeration Type Documentation

◆ MaybeTag

enum MaybeTag
Enumerator
MaybeTag_Nothing 

Nothing tag - indicates absence of a value.

MaybeTag_Just 

Just tag - indicates presence of a value.