OOP framework for standard C99

GitHub | PDF

1. Overview

Cbject makes it easier to write object oriented code in C.

1.1. Features

  • Objects

  • Classes

  • Inheritance

  • Polymorphism

  • Linked lists

1.2. Usage

Example 1. How to add it to a project

Include the following header file:

#include "cbject.h"
Example 2. How to create an object
cbject_Object * object = cbject_Object_init(cbject_alloc(cbject_Object));
uint64_t hashCode = cbject_hashCode(object);
cbject_release(object);
Example 3. How to declare a custom class
#include "../cbject/cbject.h"

typedef struct Greeting Greeting;
typedef struct Greeting_Class Greeting_Class;

struct Greeting_Class {
    cbject_Object_Class super;
};

Greeting * Greeting_init(Greeting * const self, char * const text);
void Greeting_print(Greeting * const self);
Greeting_Class * Greeting_Class_instance(void);
Example 4. How to implement a custom class
#include "Greeting.h"
#include <stdio.h>

#define cbject_Class (Greeting, cbject_Object)

struct Greeting {
    cbject_Object super;
    char * text;
};

cbject_noPool;

Greeting * Greeting_init(Greeting * const self, char * const text) {
    cbject_init(self);
    self->text = text;
    return self;
}

void Greeting_print(Greeting * const self) {
    printf("%s\n", self->text);
}

Greeting_Class * Greeting_Class_instance(void) {
    static Greeting_Class self;
    cbject_doOnce {
        cbject_Class_setup(&self);
    }
    return &self;
}

#undef cbject_Class
Example 5. How to use a custom class
// Allocate and initialize a Greeting object
Greeting * greeting = Greeting_init(cbject_alloc(Greeting), "Hello Cbject!");
// Call Greeting print function on the greeting object
Greeting_print(greeting);
// Free memory allocated for the Greeting object
cbject_release(greeting);

1.3. cbject_Object model

diag building blocks
Figure 1. Building blocks
diag rectangle class example
Figure 2. Rectangle class example

2. API

2.1. cbject

2.1.1. Overview

Cbject framework

2.2. cbject_config

2.2.1. Overview

Cbject configuration

2.2.2. Macros

cbject_config_useHeap
#define cbject_config_useHeap configValue

Heap config

Values
  • true

  • false

cbject_config_useStaticPool
#define cbject_config_useStaticPool configValue

Static pool config

Values
  • true

  • false

cbject_config_useLinkedList
#define cbject_config_useLinkedList configValue

LinkedList config

Values
  • true

  • false

cbject_config_linkedListPoolSize
#define cbject_config_linkedListPoolSize configValue

LinkedList pool size config

Values
  • >= 0

cbject_config_useNode
#define cbject_config_useNode configValue

Node config

Values
  • true

  • false

cbject_config_nodePoolSize
#define cbject_config_nodePoolSize configValue

Node pool size config

Values
  • >= 0

cbject_config_useSingleton
#define cbject_config_useSingleton configValue

Singleton config

Values
  • true

  • false

2.3. cbject_Object

2.3.1. Overview

diag object
Figure 3. Context diagram

The building block. All objects defined in Cbject need to extend cbject_Object.

2.3.2. Types

cbject_Object
typedef struct cbject_Object cbject_Object;

Typedef for struct cbject_Object

cbject_Object_Class
typedef struct cbject_Object_Class cbject_Object_Class;

Typedef for struct cbject_Object_Class

cbject_Object_PoolUsageStatus
#if (cbject_config_useStaticPool == true)
typedef enum {
    cbject_Object_PoolUsageStatus_free = 0,
    cbject_Object_PoolUsageStatus_inUse
} cbject_Object_PoolUsageStatus;
#endif

Typedef and struct definition for cbject_Object_PoolUsageStatus

Remark

Used for static pool functionality

Values
  • free

  • inUse

cbject_Object_Source
#if ((cbject_config_useStaticPool == true) || (cbject_config_useHeap == true))
typedef enum {
    cbject_Object_Source_stack,
#if (cbject_config_useHeap == true)
    cbject_Object_Source_heap,
#endif
#if (cbject_config_useStaticPool == true)
    cbject_Object_Source_staticPool
#endif
} cbject_Object_Source;
#endif

Typedef and struct definition for cbject_Object_Source

Remark

Used if heap or static pool usage is activated

Values
  • free

  • inUse

struct cbject_Object
struct cbject_Object {
    cbject_Object_Class * klass;
    size_t referenceCount;
#if ((cbject_config_useStaticPool == true) || (cbject_config_useHeap == true))
    cbject_Object_Source source;
#if (cbject_config_useStaticPool == true)
    cbject_Object_PoolUsageStatus poolUsageStatus;
#endif
#endif
};

Definition of struct cbject_Object

Members
  • klass - cbject_Object_Class reference

  • referenceCount - The reference count (number of owners of the object)

  • source - Source from where the object was created (stack/heap/staticPool)

  • poolUsageStatus - Usage status of object (free/inUse)

struct cbject_Object_Class
struct cbject_Object_Class {
    char const * name;
    size_t instanceSize;
    cbject_Object_Class const * superClass;
#if (cbject_config_useStaticPool == true)
    cbject_Object * pool;
    size_t poolSize;
    cbject_Object * poolFirstFreeObject;
    cbject_Object * (*acquire)(cbject_Object_Class * const self);
#endif
#if (cbject_config_useHeap == true)
    cbject_Object * (*alloc)(cbject_Object_Class * const self);
#endif
    uint64_t (*hashCode)(cbject_Object const * const self);
    cbject_Object * (*copy)(cbject_Object const * const self, cbject_Object * const object);
    bool (*equals)(cbject_Object const * const self, cbject_Object const * const object);
    cbject_Object * (*terminate)(cbject_Object * self);
};

Definition of struct cbject_Object_Class

Members
  • name - Name of the class

  • instanceSize - Memory size for an instance of the class

  • superClass - Super class reference

  • pool - Reference to the object static pool

  • poolSize - Size of pool (number of objects in pool)

  • poolFirstFreeObject - Reference to the first free object in the pool

  • acquire - Acquire method reference

  • alloc - Alloc method reference

  • hashCode - Hash code method reference

  • copy - Copy method reference

  • equals - Equals method reference

  • terminate - Terminate method reference

2.3.3. Functions

cbject_Object_Class_acquire()
#if (cbject_config_useStaticPool == true)
cbject_Object * cbject_Object_Class_acquire(cbject_Object_Class * const self);
#endif

Acquires an object from the static pool

Params
  • self - cbject_Object_Class reference

Return

Reference of the acquired object

cbject_Object_Class_alloc()
#if (cbject_config_useHeap == true)
cbject_Object * cbject_Object_Class_alloc(cbject_Object_Class * const self);
#endif

Allocates an object in heap memory

Params
  • self - cbject_Object_Class reference

Return

Reference of the allocated object

cbject_Object_init()
cbject_Object * cbject_Object_init(cbject_Object * const self);

Initializes an object

Params
  • self - cbject_Object reference

Return

Initialized object

cbject_Object_allocHelper()
cbject_Object * cbject_Object_allocHelper(
    cbject_Object * const self, cbject_Object_Class * const klass,
#if ((cbject_config_useStaticPool == true) || (cbject_config_useHeap == true))
    cbject_Object_Source const source
#endif
);

Sets the class of the object and other proprieties needed for allocation

Params
  • self - cbject_Object reference

  • klass - cbject_Object_Class reference

  • source - cbject_Object_Source (optional - depends on heap and static pool config)

Return

Reference to the object

cbject_Object_copy()
cbject_Object * cbject_Object_copy(cbject_Object const * const self, cbject_Object * const object);

Copies the object to the provided instance.

Params
  • self - cbject_Object reference

  • object - Reference of a new object in which to copy the original one

Return

Reference of object

cbject_Object_equals()
bool cbject_Object_equals(cbject_Object const * const self, cbject_Object const * const object);

Compares two objects

Params
  • self - cbject_Object reference

  • object - Reference for the compared object

Return
  • true - If the objects are equal

  • false - If the objects are different

cbject_Object_hashCode()
uint64_t cbject_Object_hashCode(cbject_Object const * const self);

Gets the hash code of the object

Params
  • self - cbject_Object reference

Return

The hash code of the object

cbject_Object_retain()
cbject_Object * cbject_Object_retain(cbject_Object * const self);

Increases the reference count of the object

Params
  • self - cbject_Object reference

Return

Reference to object

cbject_Object_release()
void * cbject_Object_release(cbject_Object * const self);

Decreases the reference count of the object and performs deallocation if reference count reaches 0

Params
  • self - cbject_Object reference

Return

NULL

cbject_Object_isOfClass()
bool cbject_Object_isOfClass(
    cbject_Object const * const self, cbject_Object_Class const * const klass
);

Checks if an object is of a given class

Params
  • self - cbject_Object reference

  • klass - Class reference

Return
  • true - If the object is of the provided class

  • false - If the object is of a different class

cbject_Object_Class_instance()
cbject_Object_Class * cbject_Object_Class_instance(void);

Gets cbject_Object_Class instance

Return

Reference of the class instance

2.3.4. Tests

test_cbject_Object_Class

Test setup of ObjectClass

Steps
  1. Get ObjectClass instance

  2. Check if object size stored in class is equal to the actual object size

  3. Check that the function pointers in the class are initialized

test_cbject_Object_init

Test initialization of cbject_Object

Steps
  1. Allocate object on stack an initialize it

  2. Check if object class points to cbject_Object_Class instance

test_cbject_Object_equals

Test equals method

Steps
  1. Allocate object on stack an initialize it

  2. Check if equals method returns true when comparing object to self

  3. Allocate another object on stack an initialize it

  4. Check if equals method returns false when comparing the two objects

test_cbject_Object_hashCode

Test hashCode method

Steps
  1. Allocate object on stack an initialize it

  2. Check if hashCode method returns the address in memory of the object

test_cbject_Object_isOfClass

Test isOfType method

Preconditions
  1. Define a dummy Test_Class which extends cbject_Object_Class

Steps
  1. Allocate object on stack an initialize it

  2. Check if isOfType method returns true when checked against cbject_Object

  3. Check if isOfType method returns false when checked against Test

test_cbject_Object_copy

Test copy method

Steps
  1. Allocate object on stack an initialize it

  2. Allocate another object on stack and copy the first object into it

  3. Check if the memory sections occupied by the two objects are equal

  4. Allocate another object on heap and copy the first object into it

  5. Check if the memory sections occupied by the two objects are equal

  6. Deallocate the object from the heap memory

2.4. cbject_Singleton

2.4.1. Overview

diag singleton
Figure 4. Context diagram

2.4.2. Types

cbject_Singleton
typedef struct cbject_Singleton cbject_Singleton;

Typedef for struct cbject_Singleton

cbject_Singleton_Class
typedef struct cbject_Singleton_Class cbject_Singleton_Class;

Typedef for struct cbject_Singleton_Class

struct cbject_Singleton
struct cbject_Singleton {
    cbject_Object super;

};

Definition of struct cbject_Singleton

Members
  • super - Parent

struct cbject_Singleton_Class
struct cbject_Singleton_Class {
    cbject_Object_Class super;
};

Definition of struct cbject_Singleton_Class

Members
  • super - Parent

2.4.3. Functions

cbject_Singleton_init()
cbject_Singleton * cbject_Singleton_init(cbject_Singleton * const self);

Initializes a singleton

Params
  • self - cbject_Singleton reference

Return

Initialized singleton

cbject_Singleton_Class_instance()
cbject_Singleton_Class * cbject_Singleton_Class_instance(void);

Gets cbject_Singleton_Class instance

Return

Reference of the class instance

2.5. cbject_Node

2.5.1. Overview

Node data structure used in linked lists

diag node
Figure 5. Context diagram

2.5.2. Types

cbject_Node
typedef struct cbject_Node cbject_Node;

Typedef for struct cbject_Node

cbject_Node_Class
typedef struct cbject_Node_Class cbject_Node_Class;

Typedef for struct cbject_Node_Class

struct cbject_Node
struct cbject_Node {
    cbject_Object super;
    cbject_Object * element;
    cbject_Node * previous;
    cbject_Node * next;

};

Definition of struct cbject_Node

Members
  • super - Parent

  • element - Reference to the element

  • previous - Reference to the previous node

  • next - Reference to the next node

struct cbject_Node_Class
struct cbject_Node_Class {
    cbject_Object_Class super;
};

Definition of struct cbject_Node_Class

Members
  • super - Parent

2.5.3. Functions

cbject_Node_init()
cbject_Node * cbject_Node_init(cbject_Node * const self, cbject_Object * const object);

Initializes a Node

Params
  • self - cbject_Node reference

  • object - Object to store in the node

Return

Initialized Node

cbject_Node_getElement()
cbject_Object * cbject_Node_getElement(cbject_Node const * const self);

Gets the data object contained in the node

Params
  • self - cbject_Node reference

Return

Data object in the node

cbject_Node_getPrevious()
cbject_Node * cbject_Node_getPrevious(cbject_Node const * const self);

Gets the previous node

Params
  • self - cbject_Node reference

Return

The previous node

cbject_Node_setPrevious()
void cbject_Node_setPrevious(cbject_Node * const self, cbject_Node * const previousNode);

Sets the previous node

Params
  • self - cbject_Node reference

  • previousNode - cbject_Node reference

cbject_Node_getNext()
cbject_Node * cbject_Node_getNext(cbject_Node const * const self);

Gets the next node

Params
  • self - cbject_Node reference

Return

The next node

cbject_Node_setNext()
void cbject_Node_setNext(cbject_Node * const self, cbject_Node * const nextNode);

Sets the next node

Params
  • self - cbject_Node reference

  • nextNode - cbject_Node reference

cbject_Node_Class_instance()
cbject_Node_Class * cbject_Node_Class_instance(void);

Gets cbject_Node_Class instance

Return

Reference of the class instance

2.5.4. Tests

test_cbject_Node_init

Test Node initialization

Steps
  1. Create an object and a node which takes the object as input

  2. Check node state

test_cbject_Node_setters

Test Node setters

Steps
  1. Create 3 nodes (node, previousNode, nextNode)

  2. Set previous and next nodes to the first node

  3. Check the node state

2.6. cbject_LinkedList

2.6.1. Overview

Linked list data structure

diag linkedList
Figure 6. Context diagram

2.6.2. Types

cbject_LinkedList
typedef struct cbject_LinkedList cbject_LinkedList;

Typedef for struct cbject_LinkedList

cbject_LinkedList_Class
typedef struct cbject_LinkedList_Class cbject_LinkedList_Class;

Typedef for struct cbject_LinkedList_Class

struct cbject_LinkedList
struct cbject_LinkedList {
    cbject_Object super;
    cbject_Object_Class const * elementClass;
    cbject_Node * first;
    cbject_Node * last;
    size_t size;
#if ((cbject_config_useHeap == true) && (cbject_config_useStaticPool == true))
    cbject_Object_Source nodeSource;
#endif
};

Definition of struct cbject_LinkedList

Members
  • super - Parent

  • elementClass - Class of the elements stored in the list

  • first - Reference to the first node in the list

  • last - Reference to the last node in the list

  • size - Size of the list (number of elements)

  • nodeSource - Source for node creation (see cbject_Object_Source - only heap/staticPool is allowed)

struct cbject_LinkedList_Class
struct cbject_LinkedList_Class {
    cbject_Object_Class super;
};

Definition of struct cbject_LinkedList_Class

Members
  • super - Parent

2.6.3. Functions

cbject_LinkedList_init()
cbject_LinkedList * cbject_LinkedList_init(
    cbject_LinkedList * const self, cbject_Object_Class const * const elementClass,
#if ((cbject_config_useHeap == true) && (cbject_config_useStaticPool == true))
    cbject_Object_Source const nodeSource
#endif
);

Initializes a LinkedList

Params
  • self - cbject_LinkedList reference

  • elementClass - Class of the elements stored in the list

  • nodeSource - Memory source for node creation (see cbject_Object_Source - only heap/staticPool is allowed)

Return

Initialized and empty LinkedList

cbject_LinkedList_isEmpty()
bool cbject_LinkedList_isEmpty(cbject_LinkedList const * const self);

Checks if list is empty

Params
  • self - cbject_LinkedList reference

Return
  • true - if list is empty

  • false - if list is not empty

cbject_LinkedList_add()
void cbject_LinkedList_add(
    cbject_LinkedList * const self, size_t const index, cbject_Object * const object
);

Adds an element to the end of the list

Params
  • self - cbject_LinkedList reference

  • index - Index in the list where to add the object

  • object - Object to be added in the list

cbject_LinkedList_addLast()
void cbject_LinkedList_addLast(cbject_LinkedList * const self, cbject_Object * const object);

Adds an element to the end of the list

Params
  • self - cbject_LinkedList reference

  • object - Object to be added in the list

cbject_LinkedList_addFirst()
void cbject_LinkedList_addFirst(cbject_LinkedList * const self, cbject_Object * const object);

Adds an element at the beginning of the list

Params
  • self - cbject_LinkedList reference

  • object - Object to be added in the list

cbject_LinkedList_remove()
void cbject_LinkedList_remove(cbject_LinkedList * const self, size_t const index);

Removes last element in the list at provided index

Params
  • self - cbject_LinkedList reference

  • index - Index in the list from where to remove the object

cbject_LinkedList_removeFirst()
void cbject_LinkedList_removeFirst(cbject_LinkedList * const self);

Removes first element in the list

Params
  • self - cbject_LinkedList reference

cbject_LinkedList_removeLast()
void cbject_LinkedList_removeLast(cbject_LinkedList * const self);

Removes last element in the list

Params
  • self - cbject_LinkedList reference

cbject_LinkedList_clear()
void cbject_LinkedList_clear(cbject_LinkedList * const self);

Removes all elements from the list

Params
  • self - cbject_LinkedList reference

cbject_LinkedList_get()
cbject_Object * cbject_LinkedList_get(cbject_LinkedList const * const self, size_t index);

Gets element at specified index

Params
  • self - cbject_LinkedList reference

  • index - index of the element to return

Return

Element at specified index

cbject_LinkedList_getFirst()
cbject_Object * cbject_LinkedList_getFirst(cbject_LinkedList const * const self);

Gets the first element in the list

Params
  • self - cbject_LinkedList reference

Return

First element in list

cbject_LinkedList_getLast()
cbject_Object * cbject_LinkedList_getLast(cbject_LinkedList const * const self);

Gets the last element in the list

Params
  • self - cbject_LinkedList reference

Return

Last element in list

cbject_LinkedList_getSize()
size_t cbject_LinkedList_getSize(cbject_LinkedList const * const self);

Gets the size of the list (number of elements)

Params
  • self - cbject_LinkedList reference

Return

Size of list (number of elements)

cbject_LinkedList_Class_instance()
cbject_LinkedList_Class * cbject_LinkedList_Class_instance(void);

Gets cbject_LinkedList_Class instance

Return

Reference of the class instance

2.6.4. Tests

test_cbject_LinkedList_init

Test LinkedList initialization

Steps
  1. Create a linked list

  2. Check class and members

  3. Terminate the linked list

test_cbject_LinkedList_addFirst

Test adding elements at beginning of LinkedList

Preconditions
  1. Define a Data_Class which extends cbject_Object_Class

Steps
  1. Create a linked list and some data objects

  2. Add the objects to the list and check the state of the list and the nodes

  3. Terminate the linked list

test_cbject_LinkedList_addLast

Test adding elements at the end of LinkedList

Steps
  1. Create a linked list and some objects

  2. Add the objects to the list and check the state of the list and the nodes

  3. Terminate the linked list

test_cbject_LinkedList_removeFirst

Test removing elements at the beginning of the list

Steps
  1. Create a linked list and some objects

  2. Add the objects to the list, remove them from the list and check the state of the list and the nodes

  3. Terminate the linked list

test_cbject_LinkedList_removeLast

Test removing elements at the end of the list

Steps
  1. Create a linked list and some objects

  2. Add the objects to the list, remove them from the list and check the state of the list and the nodes

  3. Terminate the linked list

test_cbject_LinkedList_addAndRemove

Test adding and removing elements at a certain index

Steps
  1. Create a linked list and some objects

  2. Add the objects to the list and check the state

  3. Remove objects from the list and check the state

  4. Release the linked list

test_cbject_LinkedList_clear

Test clearing elements from a list

Steps
  1. Create a linked list and some objects

  2. Add the objects to the list, clear the list and check the state of the list and the nodes

  3. Terminate the linked list

2.7. cbject_internal

2.7.1. Overview

TODO

2.7.2. Macros

cbject_Class_setup()
cbject_Class_setup(self)

Populates the class instance

Remark

cbject_Class must be defined before using this macro

Params
  • self - Class reference

cbject_getClass()
cbject_getClass(object)

Gets the class of an object

Params
  • object - cbject_Object reference

Return

Class reference

cbject_getInstanceSize()
cbject_getInstanceSize(object)

Gets the size in memory of an object

Params
  • object - cbject_Object reference

Return

The size in memory of the object

cbject_acquire()
cbject_acquire(type)

Acquires an object from the static pool

Remarks

Calls cbject_Object_Class_acquire() and does the necessary casting

Params
  • type - Name of class

Return

Reference of the acquired object

cbject_alloc()
cbject_alloc(type)

Allocates an object in heap memory

Remarks

Calls cbject_Object_Class_alloc() and does the necessary casting

Params
  • type - Name of class

Return

Reference of the allocated object

cbject_stackAlloc()
cbject_stackAlloc(type)

Allocates an object on the stack

Params
  • type - Name of class

Return

Reference of the allocated memory

cbject_hashCode()
cbject_hashCode(self)

Gets the hash code of the object

Remarks

Calls cbject_Object_hashCode() and does the necessary casting

Params
  • self - cbject_Object reference

Return

The hash code of the object

cbject_equals()
cbject_equals(self, object)

Compares two objects

Remarks

Calls cbject_Object_equals() and does the necessary casting

Params
  • self - cbject_Object reference

  • object - Reference for the compared object

Return
  • true - If the objects are equal

  • false - If the objects are different

cbject_copy()
cbject_copy(self, object)

Copies the object to the provided instance.

Remarks

Calls cbject_Object_copy() and does the necessary casting

Params
  • self - cbject_Object reference

  • object - Reference of a new object in which to copy the original one

Return

Reference of object

cbject_retain()
cbject_retain(self)

Increases the reference count of the object

Remarks

Calls cbject_Object_retain() and does the necessary casting

Params
  • self - cbject_Object reference

Return

Reference to object

cbject_release()
cbject_release(self)

Decreases the reference count of the object and performs deallocation if reference count reaches 0

Remarks

Calls cbject_Object_release() and does the necessary casting

Params
  • self - cbject_Object reference

Return

NULL

cbject_allocPool()
cbject_allocPool(poolSize)

Allocates a static pool

Remarks

cbject_Class must be defined before using this macro

Params
  • poolSize - Size of pool (number of objects in pool)

cbject_noPool
cbject_noPool

Declares a null static pool

Remarks

cbject_Class must be defined before using this macro Use instead of cbject_allocPool if no static pool is needed

cbject_doOnce
cbject_doOnce

Runs a block of code only once

Usage
cbject_doOnce {
    functionCall();
    anotherFunctionCall();
}
Remark

Not thread safe

cbject_invokeMethod()
cbject_invokeMethod(method, ...)

Polymorphic call of an object method

Remarks

cbject_Class must be defined before using this macro

Params
  • method - Name of the method

  • …​

    • object - cbject_Object reference

    • …​ - Method params

Return

Depends on the called method

cbject_invokeClassMethod()
cbject_invokeClassMethod(method, ...)

Polymorphic call of a class method

Remarks

cbject_Class must be defined before using this macro

Params
  • method - Name of the method

  • …​ - Method params

Return

Depends on the called method

cbject_invokeSuperMethod()
cbject_invokeSuperMethod(type, method, ...)

Polymorphic call of a super method (object or class)

Remarks

cbject_Class must be defined before using this macro

Params
  • type - Name of the class

  • method - Name of the method

  • …​

    • self - cbject_Object reference (optional - in case of object method)

    • …​ - Method params

Return

Depends on the called method

cbject_Array_getLength()
cbject_Array_getLength(self)

Gets length of an array

Params
  • self - Array for which to get the length

cbject_assertStatic()
cbject_assertStatic(expression, identifier)

Compile time assert

Params
  • expression - Expression to assert

  • identifier - An identifier to describe the assertion

cbject_Token_concat()
cbject_Token_concat(self, token)

Concatenates otherToken after the provided token

Params
  • self - Token

  • token - Token to add after the provided token

cbject_Token_concatIndirect()
cbject_Token_concatIndirect(self, token)

Concatenates otherToken after the provided token indirectly

Params
  • self - Token

  • token - Token to add after the provided token

cbject_Token_stringify()
cbject_Token_stringify(self)

Stringifies the provided token

Params
  • self - Token

cbject_Token_stringifyIndirect()
cbject_Token_stringifyIndirect(self)

Stringifies the provided token indirectly

Params
  • self - Token

cbject_VaArgs_getFirst()
cbject_VaArgs_getFirst(...)

Gets first argument from VA_ARGS

Params
  • …​ - VA_ARGS

cbject_VaArgs_getSecond()
cbject_VaArgs_getSecond(...)

Gets second argument from VA_ARGS

Params
  • …​ - VA_ARGS

cbject_VaArgs_getRest()
cbject_VaArgs_getRest(...)

Gets list of arguments from VA_ARGS except the first

Remark
  • Comma is added before the list

  • Supports max 99 arguments

Params
  • …​ - VA_ARGS

cbject_Pair_getFirst()
cbject_Pair_getFirst(self)

Gets first element from pair

Params
  • self - (first, second)

cbject_Pair_getSecond()
cbject_Pair_getSecond(self)

Gets second element from pair

Params
  • self - (first, second)