Metalang99 1.13.3
Full-blown preprocessor metaprogramming
tuple.h File Reference

Tuples: (x, y, z). More...

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

Go to the source code of this file.

Macros

#define ML99_tuple(...)   ML99_call(ML99_tuple, __VA_ARGS__)
 Transforms a sequence of arguments into (...). More...
 
#define ML99_tupleEval(...)   ML99_call(ML99_tupleEval, __VA_ARGS__)
 Transforms a sequence of arguments into (v(...)). More...
 
#define ML99_untuple(x)   ML99_call(ML99_untuple, x)
 Untuples the tuple x, leaving the result unevaluated. More...
 
#define ML99_untupleChecked(x)   ML99_call(ML99_untupleChecked, x)
 The same as ML99_untuple. More...
 
#define ML99_untupleEval(x)   ML99_call(ML99_untupleEval, x)
 Untuples the tuple x and evaluates the result. More...
 
#define ML99_isTuple(x)   ML99_call(ML99_isTuple, x)
 Tests whether x is inside parentheses or not. More...
 
#define ML99_isUntuple(x)   ML99_call(ML99_isUntuple, x)
 The inverse of ML99_isTuple. More...
 
#define ML99_tupleCount(x)   ML99_call(ML99_tupleCount, x)
 Computes the count of items in the tuple x. More...
 
#define ML99_tupleIsSingle(x)   ML99_call(ML99_tupleIsSingle, x)
 Tells if the tuple x contains only one item or not. More...
 
#define ML99_tupleGet(i)   ML99_PRIV_CAT(ML99_PRIV_tupleGet_, i)
 Expands to a metafunction extracting the i -indexed element of a tuple. More...
 
#define ML99_tupleTail(x)   ML99_call(ML99_tupleTail, x)
 Extracts the tuple's tail. More...
 
#define ML99_tupleAppend(x, ...)   ML99_call(ML99_tupleAppend, x, __VA_ARGS__)
 Appends provided variadic arguments to the tuple x. More...
 
#define ML99_tuplePrepend(x, ...)   ML99_call(ML99_tuplePrepend, x, __VA_ARGS__)
 Prepends provided variadic arguments to the tuple x. More...
 
#define ML99_tupleForEach(f, x)   ML99_call(ML99_tupleForEach, f, x)
 A shortcut for ML99_variadicsForEach(f, ML99_untuple(x)).
 
#define ML99_tupleForEachI(f, x)   ML99_call(ML99_tupleForEachI, f, x)
 A shortcut for ML99_variadicsForEachI(f, ML99_untuple(x)).
 
#define ML99_assertIsTuple(x)   ML99_call(ML99_assertIsTuple, x)
 Emits a fatal error if x is not a tuple, otherwise results in emptiness. More...
 
#define ML99_TUPLE(...)   (__VA_ARGS__)
 
#define ML99_UNTUPLE(x)   ML99_PRIV_EXPAND x
 
#define ML99_IS_TUPLE(x)   ML99_PRIV_IS_TUPLE(x)
 
#define ML99_IS_UNTUPLE(x)   ML99_PRIV_IS_UNTUPLE(x)
 
#define ML99_TUPLE_COUNT(x)   ML99_VARIADICS_COUNT(ML99_UNTUPLE(x))
 
#define ML99_TUPLE_IS_SINGLE(x)   ML99_VARIADICS_IS_SINGLE(ML99_UNTUPLE(x))
 
#define ML99_TUPLE_GET(i)   ML99_PRIV_CAT(ML99_PRIV_TUPLE_GET_, i)
 
#define ML99_TUPLE_TAIL(x)   ML99_VARIADICS_TAIL(ML99_UNTUPLE(x))
 
#define ML99_TUPLE_APPEND(x, ...)   (ML99_UNTUPLE(x), __VA_ARGS__)
 
#define ML99_TUPLE_PREPEND(x, ...)   (__VA_ARGS__, ML99_UNTUPLE(x))
 

Detailed Description

Tuples: (x, y, z).

A tuple is represented as (x1, ..., xN). Tuples are a convenient way to deal with product types. For example:

[examples/rectangle.c]

// Computes the area of a rectangle.
#include <metalang99.h>
#define rect(width, height) ML99_tuple(width, height)
#define rectWidth ML99_tupleGet(0)
#define rectHeight ML99_tupleGet(1)
#define rectArea(rect) ML99_mul(rectWidth(rect), rectHeight(rect))
/*
* 15
* +------------------------------+
* | |
* | |
* | | 7
* | |
* | |
* +------------------------------+
*/
#define RECTANGLE rect(v(15), v(7))
ML99_ASSERT_EQ(rectArea(RECTANGLE), v(15 * 7));
int main(void) {}
#define ML99_ASSERT_EQ(lhs, rhs)
Asserts ML99_EVAL(lhs) == ML99_EVAL(rhs) at compile-time.
Definition: assert.h:58
#define v(...)
A value that is pasted as-is; no evaluation occurs on provided arguments.
Definition: lang.h:145
Note
Tuples are more time and space-efficient than lists, but export less functionality; if a needed function is missed, invoking ML99_list and then manipulating with the resulting Cons-list might be helpful.

Macro Definition Documentation

◆ ML99_assertIsTuple

#define ML99_assertIsTuple (   x)    ML99_call(ML99_assertIsTuple, x)

Emits a fatal error if x is not a tuple, otherwise results in emptiness.

Examples

#define F_IMPL(x) ML99_TERMS(ML99_assertIsTuple(v(x)), ML99_untuple(v(x)))
// 1, 2, 3
ML99_call(F, v((1, 2, 3)))
// A compile-time tuple mismatch error.
ML99_call(F, v(123))
#define ML99_call(op,...)
Invokes a metafunction with arguments.
Definition: lang.h:33
Tuples: (x, y, z).

◆ ML99_isTuple

#define ML99_isTuple (   x)    ML99_call(ML99_isTuple, x)

Tests whether x is inside parentheses or not.

The preconditions are the same as of ML99_isUntuple.

Examples

// 0
// 1
ML99_isTuple(v((123)))
#define ML99_isTuple(x)
Tests whether x is inside parentheses or not.
Definition: tuple.h:113

◆ ML99_isUntuple

#define ML99_isUntuple (   x)    ML99_call(ML99_isUntuple, x)

The inverse of ML99_isTuple.

x must be either of these forms:

  • (...) (reported as non-untupled)
  • (...) (...) ... (reported as untupled)
  • anything else not beginning with (...) (reported as untupled)

For example (respectively):

  • (~, ~, ~) (non-untupled)
  • (~, ~, ~) (~, ~, ~) or (~, ~, ~) (~, ~, ~) abc (untupled)
  • 123 or 123 (~, ~, ~) (untupled)

Examples

// 1
// 0
// 1
ML99_isUntuple(v((123) (456) (789)))
#define ML99_isUntuple(x)
The inverse of ML99_isTuple.
Definition: tuple.h:143

◆ ML99_tuple

#define ML99_tuple (   ...)    ML99_call(ML99_tuple, __VA_ARGS__)

Transforms a sequence of arguments into (...).

Examples

// (1, 2, 3)
ML99_tuple(v(1, 2, 3))
#define ML99_tuple(...)
Transforms a sequence of arguments into (...).
Definition: tuple.h:38

◆ ML99_tupleAppend

#define ML99_tupleAppend (   x,
  ... 
)    ML99_call(ML99_tupleAppend, x, __VA_ARGS__)

Appends provided variadic arguments to the tuple x.

Examples

// (1, 2, 3)
#define ML99_tupleAppend(x,...)
Appends provided variadic arguments to the tuple x.
Definition: tuple.h:225

◆ ML99_tupleCount

#define ML99_tupleCount (   x)    ML99_call(ML99_tupleCount, x)

Computes the count of items in the tuple x.

At most 63 items can be contained in x.

Examples

// 3
ML99_tupleCount(v((~, ~, ~)))
// 1
#define ML99_tupleCount(x)
Computes the count of items in the tuple x.
Definition: tuple.h:162

◆ ML99_tupleEval

#define ML99_tupleEval (   ...)    ML99_call(ML99_tupleEval, __VA_ARGS__)

Transforms a sequence of arguments into (v(...)).

Examples

// (v(1, 2, 3))
ML99_tupleEval(v(1, 2, 3))
#define ML99_tupleEval(...)
Transforms a sequence of arguments into (v(...)).
Definition: tuple.h:55
Deprecated:
I have seen no single use case over time. Please, open an issue if you need this function.

◆ ML99_tupleGet

#define ML99_tupleGet (   i)    ML99_PRIV_CAT(ML99_PRIV_tupleGet_, i)

Expands to a metafunction extracting the i -indexed element of a tuple.

i can range from 0 to 7, inclusively.

Examples

// 2
ML99_tupleGet(1)(v((1, 2, 3)))
#define ML99_tupleGet(i)
Expands to a metafunction extracting the i -indexed element of a tuple.
Definition: tuple.h:195

◆ ML99_tupleIsSingle

#define ML99_tupleIsSingle (   x)    ML99_call(ML99_tupleIsSingle, x)

Tells if the tuple x contains only one item or not.

Examples

// 1
// 0
ML99_tupleIsSingle(v((~, ~, ~)))
#define ML99_tupleIsSingle(x)
Tells if the tuple x contains only one item or not.
Definition: tuple.h:179

◆ ML99_tuplePrepend

#define ML99_tuplePrepend (   x,
  ... 
)    ML99_call(ML99_tuplePrepend, x, __VA_ARGS__)

Prepends provided variadic arguments to the tuple x.

Examples

// (1, 2, 3)
#define ML99_tuplePrepend(x,...)
Prepends provided variadic arguments to the tuple x.
Definition: tuple.h:239

◆ ML99_tupleTail

#define ML99_tupleTail (   x)    ML99_call(ML99_tupleTail, x)

Extracts the tuple's tail.

x must contain at least two elements.

Examples

// 2, 3
ML99_tupleTail(v((1, 2, 3)))
#define ML99_tupleTail(x)
Extracts the tuple's tail.
Definition: tuple.h:211

◆ ML99_untuple

#define ML99_untuple (   x)    ML99_call(ML99_untuple, x)

Untuples the tuple x, leaving the result unevaluated.

If x is not a tuple, it emits a fatal error.

Examples

// 1, 2, 3
ML99_untuple(v((1, 2, 3)))
#define ML99_untuple(x)
Untuples the tuple x, leaving the result unevaluated.
Definition: tuple.h:71

◆ ML99_untupleChecked

#define ML99_untupleChecked (   x)    ML99_call(ML99_untupleChecked, x)

The same as ML99_untuple.

Deprecated:
Use ML99_untuple instead.

◆ ML99_untupleEval

#define ML99_untupleEval (   x)    ML99_call(ML99_untupleEval, x)

Untuples the tuple x and evaluates the result.

Examples

// 1, 2, 3
ML99_untupleEval(v((v(1, 2, 3))))
#define ML99_untupleEval(x)
Untuples the tuple x and evaluates the result.
Definition: tuple.h:94
Deprecated:
For the same reason as ML99_tupleEval.