Skip to content

Commit

Permalink
Finish implementing the type system
Browse files Browse the repository at this point in the history
  • Loading branch information
cm-jones committed Apr 27, 2024
1 parent 8779f44 commit 4aa8bb5
Show file tree
Hide file tree
Showing 3 changed files with 202 additions and 0 deletions.
66 changes: 66 additions & 0 deletions docs/dsc_type.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
```markdown
# DSC Type System

The DSC library provides a type system to support generic containers that can store elements of different data types. The type system is defined in the `dsc_type.h` header file and includes an enumeration `DSCType` representing various data types, as well as a function `dsc_type_of` for determining the type of a given data pointer.

## DSCType Enumeration

The `DSCType` enumeration defines a set of constants representing different data types that can be used with the containers in the DSC library. The available constants are:

- `DSC_TYPE_UNKNOWN`: Unknown or unrecognized type.
- `DSC_TYPE_CHAR`: Character type.
- `DSC_TYPE_UCHAR`: Unsigned character type.
- `DSC_TYPE_SHORT`: Short integer type.
- `DSC_TYPE_USHORT`: Unsigned short integer type.
- `DSC_TYPE_INT`: Integer type.
- `DSC_TYPE_UINT`: Unsigned integer type.
- `DSC_TYPE_LONG`: Long integer type.
- `DSC_TYPE_ULONG`: Unsigned long integer type.
- `DSC_TYPE_LLONG`: Long long integer type.
- `DSC_TYPE_ULLONG`: Unsigned long long integer type.
- `DSC_TYPE_FLOAT`: Single-precision floating-point type.
- `DSC_TYPE_DOUBLE`: Double-precision floating-point type.
- `DSC_TYPE_LDOUBLE`: Long double-precision floating-point type.
- `DSC_TYPE_STRING`: String type (character pointer).
- `DSC_TYPE_BOOL`: Boolean type.
- `DSC_TYPE_POINTER`: Generic pointer type.

These constants can be used to specify the type of elements stored in the containers provided by the DSC library.

## dsc_type_of Function

The `dsc_type_of` function is used to determine the type of a given data pointer. It takes a void pointer to the data and attempts to determine its type based on the size of the dereferenced pointer. The function compares the size of the dereferenced pointer with the sizes of known types defined in the `DSCType` enum and returns the corresponding `DSCType` value if a match is found. If no match is found, it returns `DSC_TYPE_UNKNOWN`.

The function signature is as follows:

```c
DSCType dsc_type_of(void *data);
```

- `data`: Pointer to the data.
- Returns: The `DSCType` value representing the type of the data, or `DSC_TYPE_UNKNOWN` if the type cannot be determined.

Note: The `dsc_type_of` function assumes that the data pointer is a valid pointer to the actual data. If the pointer is invalid or points to a different type than the one stored in the container, the behavior is undefined. It is the caller's responsibility to ensure that the data pointer is valid and points to the correct type.

## Usage Example

Here's an example of how to use the `DSCType` enum and the `dsc_type_of` function:

```c
int value = 42;
void *data = &value;

DSCType type = dsc_type_of(data);

if (type == DSC_TYPE_INT) {
printf("The data is of type int.\n");
} else {
printf("The data is of unknown type.\n");
}
```

In this example, we declare an integer variable `value` and obtain a void pointer `data` to its address. We then use the `dsc_type_of` function to determine the type of the data pointed to by `data`. If the type matches `DSC_TYPE_INT`, we print a message indicating that the data is of type int. Otherwise, we print a message indicating that the data is of unknown type.

## Conclusion

The DSC type system provides a way to handle different data types in generic containers. By using the `DSCType` enum and the `dsc_type_of` function, you can specify and determine the types of elements stored in the containers. However, it's important to ensure that the data pointers passed to the containers and the `dsc_type_of` function are valid and point to the correct types to avoid undefined behavior.
89 changes: 89 additions & 0 deletions include/dsc_type.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* This file is part of libdsc.
*
* libdsc is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* libdsc is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* libdsc. If not, see <https://www.gnu.org/licenses/>.
*/

#ifndef __DSC_TYPE_H__
#define __DSC_TYPE_H__

/**
* @enum DSCType
* @brief Represents the data types available in the DSC library.
*
* The DSCType enum defines a set of constants representing different data types
* that can be used with the containers in the DSC library. It includes commonly
* used primitive types, as well as some additional types like strings, booleans,
* and pointers.
*
* @constant DSC_TYPE_UNKNOWN Unknown or unrecognized type.
* @constant DSC_TYPE_CHAR Character type.
* @constant DSC_TYPE_UCHAR Unsigned character type.
* @constant DSC_TYPE_SHORT Short integer type.
* @constant DSC_TYPE_USHORT Unsigned short integer type.
* @constant DSC_TYPE_INT Integer type.
* @constant DSC_TYPE_UINT Unsigned integer type.
* @constant DSC_TYPE_LONG Long integer type.
* @constant DSC_TYPE_ULONG Unsigned long integer type.
* @constant DSC_TYPE_LLONG Long long integer type.
* @constant DSC_TYPE_ULLONG Unsigned long long integer type.
* @constant DSC_TYPE_FLOAT Single-precision floating-point type.
* @constant DSC_TYPE_DOUBLE Double-precision floating-point type.
* @constant DSC_TYPE_LDOUBLE Long double-precision floating-point type.
* @constant DSC_TYPE_STRING String type (character pointer).
* @constant DSC_TYPE_BOOL Boolean type.
* @constant DSC_TYPE_POINTER Generic pointer type.
*/
typedef enum DSCType {
DSC_TYPE_UNKNOWN,
DSC_TYPE_CHAR,
DSC_TYPE_UCHAR,
DSC_TYPE_SHORT,
DSC_TYPE_USHORT,
DSC_TYPE_INT,
DSC_TYPE_UINT,
DSC_TYPE_LONG,
DSC_TYPE_ULONG,
DSC_TYPE_LLONG,
DSC_TYPE_ULLONG,
DSC_TYPE_FLOAT,
DSC_TYPE_DOUBLE,
DSC_TYPE_LDOUBLE,
DSC_TYPE_STRING,
DSC_TYPE_BOOL,
DSC_TYPE_POINTER
} DSCType;

/**
* @brief Determines the type of the data pointed to by a void pointer.
*
* The dsc_type_of function takes a void pointer to the data and attempts to
* determine its type based on the size of the dereferenced pointer. It compares
* the size of the dereferenced pointer with the sizes of known types defined in
* the DSCType enum and returns the corresponding DSCType value if a match is
* found. If no match is found, it returns DSC_TYPE_UNKNOWN.
*
* @param data Pointer to the data.
* @return The DSCType value representing the type of the data, or DSC_TYPE_UNKNOWN
* if the type cannot be determined.
*
* @note This function assumes that the data pointer is a valid pointer to the
* actual data. If the pointer is invalid or points to a different type
* than the one stored in the container, the behavior is undefined.
* It is the caller's responsibility to ensure that the data pointer is
* valid and points to the correct type.
*/
DSCType dsc_type_of(void *data);

#endif // __DSC_TYPE_H__
47 changes: 47 additions & 0 deletions src/dsc_type.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* This file is part of libdsc.
*
* libdsc is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* libdsc is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* libdsc. If not, see <https://www.gnu.org/licenses/>.
*/

#include <stdbool.h>

#include "../include/dsc_type.h"

#define CHECK_TYPE(type, enum_type) \
if (sizeof(*(type *)data) == sizeof(type)) { \
return enum_type; \
}

DSCType dsc_type_of(void *data) {
CHECK_TYPE(char, DSC_TYPE_CHAR)
CHECK_TYPE(unsigned char, DSC_TYPE_UCHAR)
CHECK_TYPE(short, DSC_TYPE_SHORT)
CHECK_TYPE(unsigned short, DSC_TYPE_USHORT)
CHECK_TYPE(int, DSC_TYPE_INT)
CHECK_TYPE(unsigned int, DSC_TYPE_UINT)
CHECK_TYPE(long, DSC_TYPE_LONG)
CHECK_TYPE(unsigned long, DSC_TYPE_ULONG)
CHECK_TYPE(long long, DSC_TYPE_LLONG)
CHECK_TYPE(unsigned long long, DSC_TYPE_ULLONG)
CHECK_TYPE(float, DSC_TYPE_FLOAT)
CHECK_TYPE(double, DSC_TYPE_DOUBLE)
CHECK_TYPE(long double, DSC_TYPE_LDOUBLE)
CHECK_TYPE(char *, DSC_TYPE_STRING)
CHECK_TYPE(bool, DSC_TYPE_BOOL)
CHECK_TYPE(void *, DSC_TYPE_POINTER)

// Unknown type
return DSC_TYPE_UNKNOWN;
}

0 comments on commit 4aa8bb5

Please sign in to comment.