# Convenience! GLib for lists, sets, maps, and strings

GLib is a versatile utility library used in many applications and frameworks, especially those in the GNOME ecosystem. It provides data structures and utilities for C programming. Here's a guide on how to use some of its core features like ArrayLists, Sets, HashMaps, and Strings, along with installation and compilation instructions for Ubuntu.

### Installing GLib in Ubuntu

1. **Update Package Lists**:
    
    ```bash
    sudo apt update
    ```
    
2. **Install GLib**:
    
    ```bash
    sudo apt install libglib2.0-dev
    ```
    

### Compiling Code with GLib

To compile a program that uses GLib, use `gcc` with the `pkg-config` utility:

```bash
gcc `pkg-config --cflags --libs glib-2.0` -o your_program your_program.c
```

Replace `your_program.c` with the name of your C source file, and `your_program` with the desired name of the compiled executable.

### Sample Code and Explanation

#### 1\. ArrayLists (GArray)

GArray is a resizable array which can hold any data type. Here's an example of using it with integers:

```c
#include <glib.h>

int main() {
    GArray *array = g_array_new(FALSE, FALSE, sizeof(int));
    int num = 15;

    // Adding elements
    g_array_append_val(array, num);

    // Accessing elements
    num = g_array_index(array, int, 0);

    // Removing an element
    g_array_remove_index(array, 0);

    // Free the array
    g_array_free(array, TRUE);

    return 0;
}
```

#### Including GLib

```c
#include <glib.h>
```

This line includes the GLib header file, which contains the necessary declarations for using the GLib library in your program.

#### main Function

```c
int main() {
```

This line starts the definition of the `main` function, which is the entry point of a C program.

#### Creating a GArray

```c
GArray *array = g_array_new(FALSE, FALSE, sizeof(int));
```

* `g_array_new`: This function creates a new `GArray`.
    
* The first argument (`FALSE`) indicates that the array should not have zero-terminated elements. This is often set to `TRUE` for arrays of characters (strings), but for an integer array, `FALSE` is appropriate.
    
* The second argument (`FALSE`) decides whether the array elements should be cleared to 0 when they are allocated. For simple data types like `int`, this is typically not necessary.
    
* The third argument (`sizeof(int)`) specifies the size of each element in the array. In this case, we are storing integers, so the size is `sizeof(int)`.
    

#### Adding an Element to the Array

```c
int num = 15;
g_array_append_val(array, num);
```

* First, an integer `num` is initialized to 15.
    
* `g_array_append_val`: This macro appends the value of `num` to the end of the array. It's a convenient way to add elements to a `GArray`.
    

#### Accessing Elements

```c
num = g_array_index(array, int, 0);
```

* `g_array_index`: This macro is used for accessing elements of the array.
    
* It takes three arguments: the array, the type of the elements (`int` in this case), and the index of the element to access (0 here, which is the first element).
    

#### Removing an Element

```c
g_array_remove_index(array, 0);
```

* This function removes an element from the array.
    
* The first argument is the array, and the second argument is the index of the element to remove. Here, it removes the element at index 0.
    

#### Freeing the Array

```c
g_array_free(array, TRUE);
```

* `g_array_free`: This function is used to free the memory allocated for the array.
    
* The first argument is the array to be freed.
    
* The second argument (`TRUE`) decides whether to free the actual element data. If set to `TRUE`, it frees the memory allocated for the elements as well. If your array holds pointers to dynamically allocated data, you might need to manually free those before calling `g_array_free`.
    

#### 2\. Sets (GHashSet)

GHashSet provides a way to store unique elements. Here's how you can use it:

```c
#include <glib.h>

int main() {
    GHashTable *set = g_hash_table_new(g_direct_hash, g_direct_equal);

    // Adding elements
    g_hash_table_add(set, GINT_TO_POINTER(1));

    // Checking if an element is in the set
    gboolean is_present = g_hash_table_contains(set, GINT_TO_POINTER(1));

    // Removing an element
    g_hash_table_remove(set, GINT_TO_POINTER(1));

    // Free the set
    g_hash_table_destroy(set);

    return 0;
}
```

The provided code snippet demonstrates the usage of `GHashTable` in GLib as a set. `GHashTable` is a versatile hash table structure that can be used to implement various data structures, including sets and maps. In this example, it's used as a set to store unique elements. Let's break down the code:

#### Creating a GHashTable

```c
GHashTable *set = g_hash_table_new(g_direct_hash, g_direct_equal);
```

* `g_hash_table_new`: This function creates a new `GHashTable`.
    
* `g_direct_hash`: A function pointer to a hashing function. `g_direct_hash` is suitable for hashing pointers or integer values directly. It basically returns the key as its own hash.
    
* `g_direct_equal`: A function pointer to a key equality function. `g_direct_equal` compares pointers for equality, which is appropriate when using the hash table as a set of integers.
    

#### Adding Elements

```c
g_hash_table_add(set, GINT_TO_POINTER(1));
```

* `g_hash_table_add`: This function adds a unique element to the set. If the element already exists in the set, the function does nothing.
    
* `GINT_TO_POINTER(1)`: This macro converts an integer to a pointer. In C, hash tables cannot directly handle integers as keys or values since they work with pointers. This is a common technique to store integers in a data structure that expects pointers.
    

#### Checking if an Element is in the Set

```c
gboolean is_present = g_hash_table_contains(set, GINT_TO_POINTER(1));
```

* `g_hash_table_contains`: This function checks whether the set contains a specific element.
    
* `GINT_TO_POINTER(1)`: Again, the integer `1` is converted to a pointer for the check.
    
* The result (TRUE or FALSE) is stored in the `gboolean` variable `is_present`.
    

#### Removing an Element

```c
g_hash_table_remove(set, GINT_TO_POINTER(1));
```

* `g_hash_table_remove`: This function removes an element from the set.
    
* The element to remove is specified by `GINT_TO_POINTER(1)`, which is the pointer representation of the integer `1`.
    

#### Freeing the Set

```c
g_hash_table_destroy(set);
```

* `g_hash_table_destroy`: This function releases all memory used by the `GHashTable`.
    
* It not only frees the memory used by the hash table structure itself but also the memory for the elements stored in it. Since in this case, the elements are simple integer pointers (not dynamically allocated memory), there's no need for additional cleanup.
    

#### 3\. HashMaps (GHashTable)

GHashTable maps keys to values. This is a small example of using it:

```c
#include <glib.h>

int main() {
    GHashTable *hash = g_hash_table_new(g_str_hash, g_str_equal);

    // Inserting key-value pairs
    g_hash_table_insert(hash, "key1", "value1");

    // Accessing value by key
    char *value = g_hash_table_lookup(hash, "key1");

    // Removing a key-value pair
    g_hash_table_remove(hash, "key1");

    // Free the hash table
    g_hash_table_destroy(hash);

    return 0;
}
```

Sure, let's go through this code snippet, which demonstrates the use of `GHashTable` as a map in GLib. A hash table is a data structure that maps keys to values, providing efficient lookup, insertion, and deletion. In GLib, `GHashTable` is a generic implementation of such a hash table. The code snippet uses strings as keys and values, which is a common use case.

#### Creating a GHashTable

```c
GHashTable *hash = g_hash_table_new(g_str_hash, g_str_equal);
```

* `g_hash_table_new`: This function creates a new `GHashTable`.
    
* `g_str_hash`: A function pointer to a hashing function for strings. It calculates a hash value for a given string key. This is important for efficiently storing and retrieving data based on string keys.
    
* `g_str_equal`: A function pointer to a key comparison function for strings. It determines how to compare two string keys for equality, which is crucial for operations like lookup and removal.
    

#### Inserting Key-Value Pairs

```c
g_hash_table_insert(hash, "key1", "value1");
```

* `g_hash_table_insert`: This function inserts a new key-value pair into the hash table.
    
* `"key1"`: The string used as the key.
    
* `"value1"`: The string used as the value associated with `"key1"`.
    
* Note: In this particular usage, the keys and values are string literals. In a more dynamic scenario, you might use dynamically allocated strings or other types of data.
    

#### Accessing Value by Key

```c
char *value = g_hash_table_lookup(hash, "key1");
```

* `g_hash_table_lookup`: This function is used to find the value associated with a given key in the hash table.
    
* `"key1"`: The key for which the value is to be retrieved.
    
* The return value is a pointer to the value associated with the key. If the key is not found in the hash table, the function returns `NULL`.
    

#### Removing a Key-Value Pair

```c
g_hash_table_remove(hash, "key1");
```

* `g_hash_table_remove`: This function removes a key-value pair from the hash table.
    
* `"key1"`: The key of the key-value pair to be removed.
    
* When a key-value pair is removed, both the key and the value are removed from the table. If you have dynamically allocated memory for keys or values, you should free it before removing them from the hash table.
    

#### Freeing the Hash Table

```c
g_hash_table_destroy(hash);
```

* `g_hash_table_destroy`: This function releases all the memory used by the `GHashTable`.
    
* It frees the memory used by the hash table structure. If the hash table contains dynamically allocated memory as keys or values, you must free them using a custom destroy function or manually free them before calling this function.
    

#### 4\. Strings (GString)

GString is a mutable string utility in GLib:

```c
#include <glib.h>

int main() {
    GString *str = g_string_new("Hello");

    // Appending to a string
    g_string_append(str, " World");

    // Accessing the string's value
    printf("%s\n", str->str);

    // Replacing part of the string
    g_string_replace(str, "World", "GLib");

    // Free the string
    g_string_free(str, TRUE);

    return 0;
}
```

This code snippet demonstrates the use of `GString`, a dynamic string utility provided by GLib. `GString` is used for string manipulation, offering more flexibility than standard C strings. Let's break down the code:

#### Creating a GString

```c
GString *str = g_string_new("Hello");
```

* `g_string_new`: This function creates a new `GString` and initializes it with the given string.
    
* `"Hello"`: The initial value of the `GString`.
    
* `str`: A pointer to the `GString` object.
    

#### Appending to a String

```c
g_string_append(str, " World");
```

* `g_string_append`: This function appends a string to the end of the `GString`.
    
* `" World"`: The string to be appended.
    
* After this operation, `str` will contain `"Hello World"`.
    

#### Accessing the String's Value

```c
printf("%s\n", str->str);
```

* `str->str`: This is how you access the actual C string (`char *`) contained within the `GString` object. `GString` maintains a null-terminated C string for compatibility.
    
* The `printf` function is then used to print the current value of the `GString`, which at this point is `"Hello World"`.
    

#### Replacing Part of the String

```c
g_string_replace(str, "World", "GLib");
```

* `g_string_replace`: This function is not a standard GLib function. Typically, `g_string_replace` would be a custom function or part of an extension to GLib. Assuming it replaces all occurrences of a substring with another substring within the `GString`.
    
* The code intends to replace `"World"` with `"GLib"` in the `GString`. However, without the implementation details of `g_string_replace`, we can't be sure how it behaves. If it works as expected, the `GString` `str` would then contain `"Hello GLib"`.
    

#### Freeing the String

```c
g_string_free(str, TRUE);
```

* `g_string_free`: This function is used to free the memory allocated for the `GString`.
    
* `str`: The `GString` to be freed.
    
* The `TRUE` argument indicates that the function should also free the character data (`str->str`). If set to `FALSE`, the function would only free the `GString` wrapper, and you would need to free `str->str` manually.
