Optional Library 0.1
A general-purpose Maybe type for C
Loading...
Searching...
No Matches
optional.h File Reference

A general-purpose Maybe type for C. More...

#include <stddef.h>

Macros

#define OPTIONAL_VERSION   0
 Returns the major version number of this library.
 
#define OPTIONAL(type_name)
 Returns the type specifier for Optionals with the supplied type name.
 
#define OPTIONAL_STRUCT(type)
 Declares an Optional struct with a default tag and the supplied type.
 
#define OPTIONAL_PRESENT(value)
 Initializes a new Optional containing the supplied value.
 
#define OPTIONAL_EMPTY
 Initializes a new empty Optional.
 
#define OPTIONAL_OF_NULLABLE(possibly_null_pointer)
 Initializes a new Optional based on a possibly null pointer.
 
#define OPTIONAL_OF_POSSIBLY_FALSY(possibly_falsy_value)
 Initializes a new Optional based on a possibly falsy value.
 
#define OPTIONAL_IS_PRESENT(optional)
 Checks if an Optional contains a value.
 
#define OPTIONAL_IS_EMPTY(optional)
 Checks if an Optional is empty.
 
#define OPTIONAL_USE_VALUE(optional)
 Returns an Optional's value.
 
#define OPTIONAL_GET_VALUE(optional)
 Returns an Optional's value as a possibly-null pointer.
 
#define OPTIONAL_OR_ELSE(optional, other)
 Returns an Optional's value, or the supplied one.
 
#define OPTIONAL_IF_PRESENT(optional, action)
 Performs the supplied action with an Optional's value.
 
#define OPTIONAL_IF_PRESENT_OR_ELSE(optional, present_action, empty_action)
 Performs either of the supplied actions with an Optional's value.
 
#define OPTIONAL_FILTER(optional, is_acceptable)
 Conditionally transforms an Optional into an empty one.
 
#define OPTIONAL_FILTER_FALSY(optional)
 Transforms an Optional containing a falsy value into an empty one.
 
#define OPTIONAL_FILTER_NULL(optional)
 Transforms an Optional containing a null pointer into an empty one.
 
#define OPTIONAL_MAP(optional, mapper, optional_type)
 Transforms the value of an Optional.
 
#define OPTIONAL_FLAT_MAP(optional, mapper)
 Transforms an empty Optional into a different one.
 
#define OPTIONAL_OR(optional, supplier)
 Transforms an empty Optional into a different one.
 
#define OPTIONAL_TAG(type_name)
 Returns the struct tag for Optionals with the supplied type name.
 
#define OPTIONAL_STRUCT_TAG(type, struct_tag)
 Declares an Optional struct with the supplied type.
 

Detailed Description

A general-purpose Maybe type for C.

This library consists of one header file only. All you need to do is copy optional.h into your project, and include it.

#include <optional.h>
A general-purpose Maybe type for C.

Since it's a header-only library, there is no library code to link against.

Remarks
Optionals are useful for representing values that may or may not be present. To indicate why a value is absent, you may want to use Results instead.
Version
0.1.0
Author
Guillermo Calvo
See also
For more information, visit the project on GitHub

Macro Definition Documentation

◆ OPTIONAL_VERSION

#define OPTIONAL_VERSION   0

Returns the major version number of this library.

◆ OPTIONAL

#define OPTIONAL ( type_name)
Value:
struct OPTIONAL_TAG(type_name)

Returns the type specifier for Optionals with the supplied type name.

For example, an Optional that can hold an int value, has a type specifier: struct optional_int.

Note
The struct tag will be generated via OPTIONAL_TAG.
Remarks
This macro is useful to define a variable of that specific type of Optionals.

Example:

OPTIONAL(pet_status) optional;
Parameters
type_nameThe value type name.
Returns
The Optional type specifier.
See also
OPTIONAL_STRUCT

◆ OPTIONAL_STRUCT

#define OPTIONAL_STRUCT ( type)
Value:
type, \
OPTIONAL_TAG(type) \
)
#define OPTIONAL_TAG(type_name)
Returns the struct tag for Optionals with the supplied type name.
Definition optional.h:492
#define OPTIONAL_STRUCT_TAG(type, struct_tag)
Declares an Optional struct with the supplied type.
Definition optional.h:518

Declares an Optional struct with a default tag and the supplied type.

Note
The struct tag will be generated via OPTIONAL_TAG.
Remarks
This macro is useful to declare Optional structs with a default tag.

Example:

OPTIONAL_STRUCT(pet_status);
Parameters
typeThe value type.
Returns
The type definition.
See also
OPTIONAL

◆ OPTIONAL_PRESENT

#define OPTIONAL_PRESENT ( value)
Value:
{ \
._empty = false, \
._value = (value) \
}

Initializes a new Optional containing the supplied value.

Example:

OPTIONAL(pet_status) optional = OPTIONAL_PRESENT(AVAILABLE);
assert(OPTIONAL_IS_PRESENT(optional));
Parameters
valueThe value.
Returns
The initializer for an Optional holding value.
See also
OPTIONAL_EMPTY
OPTIONAL_OF_NULLABLE
OPTIONAL_OF_POSSIBLY_FALSY

◆ OPTIONAL_EMPTY

#define OPTIONAL_EMPTY
Value:
{ \
._empty = true, \
}

Initializes a new empty Optional.

Example:

OPTIONAL(pet_status) optional = OPTIONAL_EMPTY;
Returns
The initializer for an empty Optional.
See also
OPTIONAL_PRESENT
OPTIONAL_OF_NULLABLE
OPTIONAL_OF_POSSIBLY_FALSY

◆ OPTIONAL_OF_NULLABLE

#define OPTIONAL_OF_NULLABLE ( possibly_null_pointer)
Value:
{ \
._empty = ((possibly_null_pointer) == NULL), \
._value = ((void) &(possibly_null_pointer), (possibly_null_pointer)) \
}

Initializes a new Optional based on a possibly null pointer.

This macro will initialize a new empty Optional if the supplied possibly_null_pointer is NULL; otherwise, it will initialize a new Optional containing the supplied pointer.

Precondition
possibly_null_pointer MUST be an lvalue.

Example:

Pet pet = NULL;
OPTIONAL(Pet) optional = OPTIONAL_OF_POSSIBLY_FALSY(pet);
assert(OPTIONAL_IS_EMPTY(optional));
Parameters
possibly_null_pointerThe possibly null pointer.
Returns
The initializer for either an empty Optional or an Optional holding possibly_null_pointer if it is not NULL.
See also
OPTIONAL_PRESENT
OPTIONAL_EMPTY
OPTIONAL_OF_POSSIBLY_FALSY

◆ OPTIONAL_OF_POSSIBLY_FALSY

#define OPTIONAL_OF_POSSIBLY_FALSY ( possibly_falsy_value)
Value:
{ \
._empty = !(possibly_falsy_value), \
._value = ((void) &(possibly_falsy_value), (possibly_falsy_value)) \
}

Initializes a new Optional based on a possibly falsy value.

This macro will initialize a new empty Optional if the supplied possibly_falsy_value evaluates to false when converted to bool; otherwise, it will initialize a new Optional containing the supplied value.

Precondition
possibly_falsy_value MUST be an lvalue.

Example:

int age = 0;
OPTIONAL(int) optional = OPTIONAL_OF_POSSIBLY_FALSY(age);
assert(OPTIONAL_IS_EMPTY(optional));
Parameters
possibly_falsy_valueThe possibly falsy value.
Returns
The initializer for either an empty Optional or an Optional holding possibly_falsy_value if it does not evaluate to false.
See also
OPTIONAL_PRESENT
OPTIONAL_EMPTY
OPTIONAL_OF_NULLABLE

◆ OPTIONAL_IS_PRESENT

#define OPTIONAL_IS_PRESENT ( optional)
Value:
(!(optional)._empty)

Checks if an Optional contains a value.

Example:

OPTIONAL(pet_status) optional = OPTIONAL_PRESENT(AVAILABLE);
bool is_present = OPTIONAL_IS_PRESENT(optional);
assert(is_present == true);
Parameters
optionalThe Optional to check for presence.
Returns
true if optional is present; otherwise false.
See also
OPTIONAL_IS_EMPTY

◆ OPTIONAL_IS_EMPTY

#define OPTIONAL_IS_EMPTY ( optional)
Value:
((optional)._empty)

Checks if an Optional is empty.

Example:

OPTIONAL(pet_status) optional = OPTIONAL_EMPTY;
bool is_empty = OPTIONAL_IS_EMPTY(optional);
assert(is_empty == true);
Parameters
optionalThe Optional to check for absence.
Returns
true if optional is empty; otherwise false.
See also
OPTIONAL_IS_PRESENT

◆ OPTIONAL_USE_VALUE

#define OPTIONAL_USE_VALUE ( optional)
Value:
((optional)._value)

Returns an Optional's value.

Precondition
optional MUST be present.
Warning
If optional is empty, the value is not initialized explicitly but it SHOULD be zeroed by the compiler.

Example:

OPTIONAL(pet_status) optional = OPTIONAL_PRESENT(AVAILABLE);
pet_status value = OPTIONAL_USE_VALUE(optional);
assert(value == AVAILABLE);
Parameters
optionalThe Optional to retrieve the value from.
Returns
optional's value.

◆ OPTIONAL_GET_VALUE

#define OPTIONAL_GET_VALUE ( optional)
Value:
( \
(void) &(optional), \
OPTIONAL_IS_EMPTY(optional) \
? NULL \
: &OPTIONAL_USE_VALUE(optional) \
)
#define OPTIONAL_USE_VALUE(optional)
Returns an Optional's value.
Definition optional.h:240

Returns an Optional's value as a possibly-null pointer.

Precondition
optional MUST be an lvalue.

Example:

OPTIONAL(pet_status) optional = OPTIONAL_PRESENT(AVAILABLE);
const pet_status *value = OPTIONAL_GET_VALUE(optional);
assert(*value == AVAILABLE);
Parameters
optionalThe Optional to retrieve the value from.
Returns
A pointer to optional's value if present; otherwise NULL.

◆ OPTIONAL_OR_ELSE

#define OPTIONAL_OR_ELSE ( optional,
other )
Value:
( \
(void) &(optional), \
OPTIONAL_IS_EMPTY(optional) \
? (other) \
: OPTIONAL_USE_VALUE(optional) \
)

Returns an Optional's value, or the supplied one.

Precondition
optional MUST be an lvalue.

Example:

OPTIONAL(pet_status) optional = OPTIONAL_EMPTY;
pet_status value = OPTIONAL_OR_ELSE(optional, PENDING);
assert(value == PENDING);
Parameters
optionalThe Optional to retrieve the value from.
otherThe alternative value.
Returns
optional's value if present; otherwise other.
See also
OPTIONAL_OR_ELSE_MAP

◆ OPTIONAL_IF_PRESENT

#define OPTIONAL_IF_PRESENT ( optional,
action )
Value:
do { \
typeof(optional) _optional = (optional); \
if (OPTIONAL_IS_PRESENT(_optional)) { \
(void) (action(OPTIONAL_USE_VALUE(_optional))); \
} \
} while(false)
#define OPTIONAL_IS_PRESENT(optional)
Checks if an Optional contains a value.
Definition optional.h:208

Performs the supplied action with an Optional's value.

If optional is present, performs the given action with the value; otherwise does nothing.

Example:

OPTIONAL(int) optional = OPTIONAL_PRESENT(123);
side_effect = 0;
OPTIONAL_IF_PRESENT(optional, set_side_effect);
assert(side_effect == 123);
Parameters
optionalThe Optional whose value will be used.
actionThe function or macro to be applied to optional's value.
See also
OPTIONAL_IF_PRESENT_OR_ELSE

◆ OPTIONAL_IF_PRESENT_OR_ELSE

#define OPTIONAL_IF_PRESENT_OR_ELSE ( optional,
present_action,
empty_action )
Value:
do { \
typeof(optional) _optional = (optional); \
if (OPTIONAL_IS_EMPTY(_optional)) { \
(void) (empty_action); \
} else { \
(void) (present_action(OPTIONAL_USE_VALUE(_optional))); \
} \
} while(false)
#define OPTIONAL_IS_EMPTY(optional)
Checks if an Optional is empty.
Definition optional.h:222

Performs either of the supplied actions with an Optional's value.

If optional is present, performs the given present-based action with the value; otherwise performs the given empty-based action.

Example:

OPTIONAL(int) optional = OPTIONAL_EMPTY;
side_effect = 0;
last_error = OK;
OPTIONAL_IF_PRESENT_OR_ELSE(optional, set_side_effect, log_error(PET_NOT_FOUND));
assert(side_effect == 0);
assert(last_error == PET_NOT_FOUND);
Parameters
optionalThe Optional whose value may be used.
present_actionThe function or macro to be applied to optional's value if present.
empty_actionThe expression to evaluate if optional is empty.
See also
OPTIONAL_IF_PRESENT

◆ OPTIONAL_FILTER

#define OPTIONAL_FILTER ( optional,
is_acceptable )
Value:
( \
(void) &(optional), \
OPTIONAL_IS_EMPTY(optional) \
|| (is_acceptable(OPTIONAL_USE_VALUE(optional))) \
? (optional) \
: (typeof(optional)) OPTIONAL_EMPTY \
)
#define OPTIONAL_EMPTY
Initializes a new empty Optional.
Definition optional.h:139

Conditionally transforms an Optional into an empty one.

Precondition
optional MUST be an lvalue.

Example:

struct pet sold = {.status = SOLD};
OPTIONAL(Pet) optional = OPTIONAL_PRESENT(&sold);
OPTIONAL(Pet) filtered = OPTIONAL_FILTER(optional, is_available);
assert(OPTIONAL_IS_EMPTY(filtered));
Parameters
optionalThe Optional to filter.
is_acceptableThe predicate function or macro to apply to the value.
Returns
If optional is present and its value is deemed not acceptable, a new empty Optional; otherwise, the supplied optional.
See also
OPTIONAL_FILTER_FALSY
OPTIONAL_FILTER_NULL

◆ OPTIONAL_FILTER_FALSY

#define OPTIONAL_FILTER_FALSY ( optional)
Value:
( \
(void) &(optional), \
OPTIONAL_IS_EMPTY(optional) \
|| !!(OPTIONAL_USE_VALUE(optional)) \
? (optional) \
: (typeof(optional)) OPTIONAL_EMPTY \
)

Transforms an Optional containing a falsy value into an empty one.

Precondition
optional MUST be an lvalue.

Example:

int age = 0;
OPTIONAL(int) optional = OPTIONAL_PRESENT(age);
OPTIONAL(int) filtered = OPTIONAL_FILTER_FALSY(optional);
assert(OPTIONAL_IS_EMPTY(filtered));
Parameters
optionalThe Optional to filter.
Returns
If optional is present and its value is not falsy, a new empty Optional; otherwise, the supplied optional.
See also
OPTIONAL_FILTER
OPTIONAL_FILTER_NULL

◆ OPTIONAL_FILTER_NULL

#define OPTIONAL_FILTER_NULL ( optional)
Value:
( \
(void) &(optional), \
OPTIONAL_IS_EMPTY(optional) \
|| OPTIONAL_USE_VALUE(optional) != NULL \
? (optional) \
: (typeof(optional)) OPTIONAL_EMPTY \
)

Transforms an Optional containing a null pointer into an empty one.

Precondition
optional MUST be an lvalue.

Example:

Pet pet = NULL;
OPTIONAL(Pet) optional = OPTIONAL_PRESENT(pet);
OPTIONAL(Pet) filtered = OPTIONAL_FILTER_NULL(optional);
assert(OPTIONAL_IS_EMPTY(filtered));
Parameters
optionalThe Optional to filter.
Returns
If optional is present and its value is not NULL, a new empty Optional; otherwise, the supplied optional.
See also
OPTIONAL_FILTER
OPTIONAL_FILTER_FALSY

◆ OPTIONAL_MAP

#define OPTIONAL_MAP ( optional,
mapper,
optional_type )
Value:
( \
(void) &(optional), \
OPTIONAL_IS_EMPTY(optional) \
? (optional_type) OPTIONAL_EMPTY \
: (optional_type) OPTIONAL_PRESENT(mapper(OPTIONAL_USE_VALUE(optional)))\
)
#define OPTIONAL_PRESENT(value)
Initializes a new Optional containing the supplied value.
Definition optional.h:121

Transforms the value of an Optional.

Precondition
optional MUST be an lvalue.

Example:

struct pet sold = {.status = SOLD};
OPTIONAL(Pet) optional = OPTIONAL_PRESENT(&sold);
OPTIONAL(pet_status) mapped = OPTIONAL_MAP(optional, PET_STATUS, typeof(mapped));
assert(OPTIONAL_USE_VALUE(mapped) == SOLD);
Parameters
optionalThe Optional whose value will be transformed.
mapperThe mapping function or macro that produces the new value.
optional_typeThe type of the transformed Optional type.
Returns
If optional is present, a new Optional holding the value produced by mapper; otherwise, the supplied optional.
See also
OPTIONAL_MAP

◆ OPTIONAL_FLAT_MAP

#define OPTIONAL_FLAT_MAP ( optional,
mapper )
Value:
( \
(void) &(optional), \
OPTIONAL_IS_EMPTY(optional) \
? (typeof(mapper(OPTIONAL_USE_VALUE(optional)))) \
: (mapper(OPTIONAL_USE_VALUE(optional))) \
)

Transforms an empty Optional into a different one.

Precondition
optional MUST be an lvalue.

Example:

struct pet sold = {.status = SOLD};
OPTIONAL(Pet) optional = OPTIONAL_PRESENT(&sold);
OPTIONAL(Pet) mapped = OPTIONAL_FLAT_MAP(optional, buy_pet);
assert(OPTIONAL_IS_EMPTY(mapped));
Parameters
optionalThe Optional that will be transformed.
mapperThe mapping function or macro that produces the new Optional if the given optional is present.
Returns
If optional is present, a new Optional produced by mapper; otherwise, the supplied optional.
See also
OPTIONAL_OR

◆ OPTIONAL_OR

#define OPTIONAL_OR ( optional,
supplier )
Value:
( \
(void) &(optional), \
OPTIONAL_IS_EMPTY(optional) \
? (supplier) \
: (typeof(supplier)) OPTIONAL_PRESENT(OPTIONAL_USE_VALUE(optional)) \
)

Transforms an empty Optional into a different one.

Precondition
optional MUST be an lvalue.

Example:

OPTIONAL(Pet) optional = OPTIONAL_EMPTY;
OPTIONAL(Pet) mapped = OPTIONAL_OR(optional, pet_get_default(PET_NOT_FOUND));
assert(strcmp(PET_NAME(OPTIONAL_USE_VALUE(mapped)), "Default pet") == 0);
Parameters
optionalThe Optional that will be transformed.
supplierThe expression that produces the new Optional if the given optional is empty.
Returns
If optional is empty, a new Optional produced by supplier; otherwise, the supplied optional.
See also
OPTIONAL_FLAT_MAP

◆ OPTIONAL_TAG

#define OPTIONAL_TAG ( type_name)
Value:
optional_ ## type_name

Returns the struct tag for Optionals with the supplied type name.

For example, an Optional that can hold an int value, has a struct tag: optional_int.

Example:

OPTIONAL(Pet) optional = OPTIONAL_EMPTY;
assert(OPTIONAL_IS_EMPTY(optional));
Parameters
type_nameThe value type name.
Returns
The Optional struct tag.
See also
OPTIONAL_STRUCT_TAG

◆ OPTIONAL_STRUCT_TAG

#define OPTIONAL_STRUCT_TAG ( type,
struct_tag )
Value:
struct struct_tag { \
bool _empty; \
type _value; \
}

Declares an Optional struct with the supplied type.

Precondition
struct_tag SHOULD be generated via OPTIONAL_TAG.
Warning
The exact sequence of members that make up an Optional struct MUST be considered part of the implementation details. Optionals SHOULD only be created and accessed using the macros provided in this header file.
Remarks
This macro is useful to declare Optional structs.

Example:

OPTIONAL(Pet) optional = OPTIONAL_EMPTY;
assert(OPTIONAL_IS_EMPTY(optional));
Parameters
typeThe value type.
struct_tagThe struct tag.
Returns
The struct declaration.
See also
OPTIONAL_STRUCT
OPTIONAL_TAG