I will be more than happy to receive suggestions, feedback, bugs and overall code review for this project
I will be more than happy to receive suggestions, feedback, bugs and overall code review for this project.
Stack Exchange network consists of 183 Q&A communities including Stack Overflow, the largest, most trusted online community for developers to learn, share their knowledge, and build their careers.
Visit Stack ExchangeTeams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about TeamsI will be more than happy to receive suggestions, feedback, bugs and overall code review for this project.
I will be more than happy to receive suggestions, feedback, bugs and overall code review for this project.
Dtype currently is same as char, when doing dtype var[size]; size bytes are reserved for var as normal char would do. The actual working of dtype is that it stores the type of variable in first 1 byte i.e var[0] = (char)type;, and stores its size info in second & third bytes as unsigned short, i.e * ( unsigned short * ) (var + 1) = size; after that any data to be stored is checked with the size, i.e * (unsigned short * ) (var + 1) and if the size is equal or greater than the data to be stored, the data is then hard-copied from fourth byte onwards, i.e from ( var + 3) and to get data, it simply checks the type and grabs the data, if type mismatch occurs, it produces a warning [ in runtime ].
-O2 flag, on my device - results may vary on yours. ) :-| No. | Normal variables doing same thing | Dtype variables doing same thing |
|---|---|---|
| 1 | ~20.945 ms on average [50+ tests] | ~21.025 ms on average [50+ tests] |
| 2 | ~19.881 ms on average [100+ tests] | ~19.997 ms on average [100+ tests] |
/**
* @file dtype.h
*
* @brief Contains the definition for `dtype` along with `dtypes` & `dtypes.*` function signatures.
*/
#ifndef DTYPE_H_INCL
#define DTYPE_H_INCL
#include <stdbool.h>
/**
* @brief the actual dtype which stores the data
* @example dtype var[size_in_bytes];
*/
typedef char dtype;
/// @brief Current size_type for `dtype`
typedef unsigned short DTYPE_SIZE;
/// @brief Display warning if true
#ifndef DTYPE_WARN_OUT
#define DTYPE_WARN_OUT true
#endif
/// @brief Immediately display errors if true
#ifndef DTYPE_ERROR_OUT
#define DTYPE_ERROR_OUT true
#endif
/// @brief Exit on error if true
#ifndef DTYPE_EXIT_ON_ERR
#define DTYPE_EXIT_ON_ERR true
#endif
/**
* @enum DTYPES_ERR
* @brief ErrorCode enums for DTYPES_ERR
*/
enum DTYPES_ERR {
DTYPE_NO_ERR,
DTYPE_SIZE_LOW,
DTYPE_SIZE_HIGH,
DTYPE_MIN_MEM,
DTYPE_VALUE_ERR,
DTYPE_NOT_INIT,
DTYPE_UNKNOWN_ERR
};
/**
* @enum DTYPES_TYPES
* @brief Typecode for identifying current type of `dtype`.
* @brief DTYPE_TYPE for normal types,
* @brief DTYPE_UTYPE for unsigned types.
*/
enum DTYPES_TYPES {
DTYPE_INVALID, // Invalid type, not initialized!
DTYPE_NONE,
DTYPE_BOOL,
DTYPE_SHORT,
DTYPE_USHORT,
DTYPE_INT,
DTYPE_UINT,
DTYPE_LONG,
DTYPE_ULONG,
DTYPE_FLOAT,
DTYPE_DOUBLE,
DTYPE_CHAR,
DTYPE_STR,
DTYPE_OBJECT, // object type -> currently holds a custom type of variable.
DTYPE_UNKNOWN // unknown type!
};
/**
* @struct __dtypes_struct
* @typedef __dtypes_struct
*
* @brief a wrapper for all dtype functions.
*/
typedef struct __dtypes_struct {
/**
* @brief Initializes the variable.
* @param var The variable to initialize.
* @param size Size of the variable in bytes
*/
void (*init)(dtype* var, DTYPE_SIZE size);
/**
* @brief Prints the current error even if there is not an error.
* @returns The ErrorCode of current error
*/
enum DTYPES_ERR (*get_error)(void);
/**
* @brief Returns the usable size of variable..
* @param var The varible to get size of.
* @returns The usable size of given variable.
*/
DTYPE_SIZE (*get_size)(dtype* var);
/**
* @brief Returns the current `typecode` of the variable..
* @param var The variable to get `typecode` of.
* @returns The typecode of given variable.
*/
enum DTYPES_TYPES (*get_type)(dtype* var);
/**
* @brief Returns the current `type` of variable..
* @param var The variable to get type from.
* @returns The `type` of variable in readable string.
*/
const char* (*get_str_type)(dtype* var);
/**
* @brief Set the type of variable..
* @param var The variable to set the type..
* @param type the typecode to set.
*/
void (*set_type)(dtype* var, enum DTYPES_TYPES);
/**
* @brief Set the content of variable to none..
* @param var The variable to set to.
*/
void (*set_none)(dtype* var);
/**
* @brief Set the content of variable to given boolean value..
* @param var The variable to set to..
* @param value The value to set to.
*/
void (*set_bool)(dtype* var, bool value);
/**
* @brief Set the content of variable to given short value..
* @param var The variable to set to..
* @param value The value to set to.
*/
void (*set_short)(dtype* var, short value);
/**
* @brief Set the content of variable to given unsigned short value..
* @param var The variable to set to..
* @param value The value to set to.
*/
void (*set_ushort)(dtype* var, unsigned short value);
/**
* @brief Set the content of variable to given integer value..
* @param var The variable to set to..
* @param value The value to set to.
*/
void (*set_int)(dtype* var, int value);
/**
* @brief Set the content of variable to given unsigned integer value..
* @param var The variable to set to..
* @param value The value to set to.
*/
void (*set_uint)(dtype* var, unsigned int value);
/**
* @brief Set the content of variable to given long integer value..
* @param var The variable to set to..
* @param value The value to set to.
*/
void (*set_long)(dtype* var, long value);
/**
* @brief Set the content of variable to given unsigned long integer value..
* @param var The variable to set to..
* @param value The value to set to.
*/
void (*set_ulong)(dtype* var, unsigned long value);
/**
* @brief Set the content of variable to given float value..
* @param var The variable to set to..
* @param value The value to set to.
*/
void (*set_float)(dtype* var, float value);
/**
* @brief Set the content of variable to given double value..
* @param var The variable to set to..
* @param value The value to set to.
*/
void (*set_double)(dtype* var, double value);
/**
* @brief Set the content of variable to given character value..
* @param var The variable to set to..
* @param value The value to set to.
*/
void (*set_char)(dtype* var, char value);
/**
* @brief Set the content of variable to given string..
* @param var The variable to set to..
* @param value The value to set to.
*/
void (*set_str)(dtype* var, char * value);
/**
* @brief Copy the contents of the object into the variable..
* @param var The variable to copy to..
* @param obj The void pointer of object to copy from..
* @param size The size of the object.
*/
void (*set_object)(dtype* var, void * obj, DTYPE_SIZE size);
/**
* @brief Get the content of variable as boolean.
* @param var The variable to get from
*/
bool (*get_bool)(dtype* var);
/**
* @brief Get the content of variable as short.
* @param var The variable to get from
*/
short (*get_short)(dtype* var);
/**
* @brief Get the content of variable as unsigned short.
* @param var The variable to get from
*/
unsigned short (*get_ushort)(dtype* var);
/**
* @brief Get the content of variable as integer.
* @param var The variable to get from
*/
int (*get_int)(dtype* var);
/**
* @brief Get the content of variable as unsigned integer.
* @param var The variable to get from
*/
unsigned int (*get_uint)(dtype* var);
/**
* @brief Get the content of variable as long integer.
* @param var The variable to get from
*/
long (*get_long)(dtype* var);
/**
* @brief Get the content of variable as unsigned long integer.
* @param var The variable to get from
*/
unsigned long (*get_ulong)(dtype* var);
/**
* @brief Get the content of variable as float.
* @param var The variable to get from
*/
float (*get_float)(dtype* var);
/**
* @brief Get the content of variable as double.
* @param var The variable to get from
*/
double (*get_double)(dtype* var);
/**
* @brief Get the content of variable as character.
* @param var The variable to get from
*/
char (*get_char)(dtype* var);
/**
* @brief Get the content of variable as string (char *).
* @param var The variable to get from
*/
char * (*get_str)(dtype* var);
/**
* @brief Get the content of variable as object [ void pointer ].
* @param var The variable to get from
*/
void * (*get_object)(dtype* var);
/**
* @brief Get the direct pointer of variable as bool *
* @brief to directly set the value / use in functions like scanf().
* @brief Also sets the current type to bool.
* @param var The variable to get pointer from.
*/
bool* (*in_bool)(dtype* var);
/**
* @brief Get the direct pointer of variable as short *
* @brief to directly set the value / use in functions like scanf().
* @brief Also sets the current type to short.
* @param var The variable to get pointer from.
*/
short* (*in_short)(dtype* var);
/**
* @brief Get the direct pointer of variable as unsigned short *
* @brief to directly set the value / use in functions like scanf().
* @brief Also sets the current type to unsigned short.
* @param var The variable to get pointer from.
*/
unsigned short* (*in_ushort)(dtype* var);
/**
* @brief Get the direct pointer of variable as int *
* @brief to directly set the value / use in functions like scanf().
* @brief Also sets the current type to integer.
* @param var The variable to get pointer from.
*/
int* (*in_int)(dtype* var);
/**
* @brief Get the direct pointer of variable as unsigned int *
* @brief to directly set the value / use in functions like scanf().
* @brief Also sets the current type to unsigned int.
* @param var The variable to get pointer from.
*/
unsigned int* (*in_uint)(dtype* var);
/**
* @brief Get the direct pointer of variable as long *
* @brief to directly set the value / use in functions like scanf().
* @brief Also sets the current type to long.
* @param var The variable to get pointer from.
*/
long* (*in_long)(dtype* var);
/**
* @brief Get the direct pointer of variable as unsigned long *
* @brief to directly set the value / use in functions like scanf().
* @brief Also sets the current type to unsigned long.
* @param var The variable to get pointer from.
*/
unsigned long* (*in_ulong)(dtype* var);
/**
* @brief Get the direct pointer of variable as float *
* @brief to directly set the value / use in functions like scanf().
* @brief Also sets the current type to float.
* @param var The variable to get pointer from.
*/
float* (*in_float)(dtype* var);
/**
* @brief Get the direct pointer of variable as double *
* @brief to directly set the value / use in functions like scanf().
* @brief Also sets the current type to double.
* @param var The variable to get pointer from.
*/
double* (*in_double)(dtype* var);
/**
* @brief Get the direct pointer of variable as char *
* @brief to directly set the value / use in functions like scanf().
* @brief Also sets the current type to char.
* @param var The variable to get pointer from.
*/
char* (*in_char)(dtype* var);
/**
* @brief Get the direct pointer of variable as char *
* @brief to directly set the value / use in functions like scanf().
* @brief Also sets the current type to string.
* @param var The variable to get pointer from.
*/
char* (*in_str)(dtype* var);
enum DTYPES_TYPES (*print)(dtype* var);
} __dtypes_struct;
__dtypes_struct dtypes;
#endif
/**
* @file dtype.c
*
* @brief contains the actual code for definition in dtype.h
*/
#include "dtype.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/// @brief Current Errorcode
enum DTYPES_ERR DTYPE_CURRENT_ERRCODE = DTYPE_NO_ERR;
/// @brief The function in which current error occured.
const char* DTYPE_CURRENT_ERRFUNC = "none";
/// @brief Current Error description.
const char* DTYPE_CURRENT_ERRDESC = "none";
// function that prints current error and returns the errcode
enum DTYPES_ERR get_error ( void )
{
// print out error
printf ("\n---------- Dtype Error ----------\n");
printf ("in function %s, errcode: %d :\n\tinfo: %s\n",
DTYPE_CURRENT_ERRFUNC, DTYPE_CURRENT_ERRCODE, DTYPE_CURRENT_ERRDESC
);
// store the current errorcode to later return
enum DTYPES_ERR ErrCode = DTYPE_CURRENT_ERRCODE;
// set the current error to null as we have printed it!
DTYPE_CURRENT_ERRFUNC = "none";
DTYPE_CURRENT_ERRCODE = DTYPE_NO_ERR;
DTYPE_CURRENT_ERRDESC = "none";
// return the errcode
return ErrCode;
}
// function that sets error as given.
void set_error ( enum DTYPES_ERR errcode, const char* fname, const char* desc )
{
// set the error
DTYPE_CURRENT_ERRCODE = errcode;
DTYPE_CURRENT_ERRFUNC = fname;
DTYPE_CURRENT_ERRDESC = desc;
// print the error via get_error () if DTYPE_ERROR_OUT is true
if ( DTYPE_ERROR_OUT)
{
get_error ();
// exit if DTYPE_EXIT_ON_ERR is true!
if ( DTYPE_EXIT_ON_ERR ) {
exit (1);
}
}
}
// set_type of the variable as provided.
void set_type ( dtype * var, enum DTYPES_TYPES type )
{
var[0] = ( char ) type;
}
// set the size of the variable as provided
void set_size ( dtype * var, DTYPE_SIZE size )
{
*( (DTYPE_SIZE*) (var+1) ) = size;
}
// get_type of the variable
enum DTYPES_TYPES get_type ( dtype * var )
{
return var[0];
}
// get_type of the the variable but in a readable format, not in typecode.
const char* get_stype ( dtype * var )
{
// self-explanatory.
switch ( get_type ( var ) )
{
case DTYPE_NONE:
return "none ( null value )";
case DTYPE_BOOL:
return "bool";
case DTYPE_SHORT:
return "short";
case DTYPE_USHORT:
return "unsigned short";
case DTYPE_INT:
return "int";
case DTYPE_UINT:
return "unsigned int";
case DTYPE_LONG:
return "long";
case DTYPE_ULONG:
return "unsigned long";
case DTYPE_FLOAT:
return "float";
case DTYPE_DOUBLE:
return "double";
case DTYPE_CHAR:
return "char";
case DTYPE_STR:
return "string ( char *)";
case DTYPE_OBJECT:
return "object ( custom )";
case DTYPE_UNKNOWN:
return "unknown";
default:
return "invalid ( not initialized )";
}
}
// get usable size of the the variable
DTYPE_SIZE get_size ( dtype * var )
{
return *( (DTYPE_SIZE*) (var+1));
}
// initialization of the variable
// this basically sets the type to DTYPE_NONE and sets the size as provided
// also has a check that size must be greater than or equal to 4.
void dt_init ( dtype * var, DTYPE_SIZE size )
{
if ( size < 4) {
set_error (DTYPE_SIZE_LOW, "init", "Size too low, < 4");
}
// store the type
set_type ( var, DTYPE_NONE);
// store the size
set_size ( var, size-DTYPE_MIN_MEM);
}
// clear the data inside the variable
void dt_clear ( dtype * var ) {
// for old c support!
DTYPE_SIZE i;
for ( i = DTYPE_MIN_MEM; i < DTYPE_MIN_MEM + get_size(var); ++i )
{
var[i] = '\0';
}
}
// internal set_object function used for setting the variable's value
bool _dtset_obj ( dtype * var, void *obj, DTYPE_SIZE size )
{
// check for initialization
if ( get_type ( var ) == DTYPE_INVALID || get_type ( var ) > DTYPE_UNKNOWN) {
set_error (
DTYPE_NOT_INIT, "internal set_object()",
"trying to set to non-initialized variable!"
);
// indicating error
return true;
}
// clear previous value before storing
dt_clear ( var );
// if the size to store is greater than
if ( size > get_size ( var ) )
{
// not enough room to store!
// indicating error!
return true;
}
// for old c support
int i;
// hardcopy every byte till given size
for ( i = 0; i < size; ++i )
{
var[i+DTYPE_MIN_MEM] = ( ( char*) obj )[i];
}
// no error
return false;
}
void dtset_none ( dtype * var )
{
// clear the data
dt_clear ( var );
// set type to none
set_type ( var, DTYPE_NONE);
}
// set function for boolean value
void dtset_bool ( dtype * var, bool value )
{
bool val = value;
// use internal set_object function to set the dtype data to value
// if error is not indicated, set the type and return
if ( !_dtset_obj ( var, &val, sizeof ( bool ) ) ) {
set_type ( var, DTYPE_BOOL);
return;
}
// set the error
set_error (DTYPE_SIZE_HIGH, "set_bool", "the variable size is too low to store bool !");
return;
}
// set function for short value
void dtset_short ( dtype * var, short value )
{
short val = value;
// use internal set obj to set data to value
// if error is not indicated, set the type and return
if ( !_dtset_obj ( var, &val, sizeof ( short ) ) ) {
set_type ( var, DTYPE_SHORT);
return;
}
//set the error
set_error (DTYPE_SIZE_HIGH, "set_short", "the variable size is too low to store short !");
return;
}
// set function for unsigned short value
void dtset_ushort ( dtype * var, unsigned short value )
{
unsigned short val = value;
// use internal set_object function to set the dtype data to value
// if error is not indicated, set the type and return
if ( !_dtset_obj ( var, &val, sizeof ( unsigned short ) ) ) {
set_type ( var, DTYPE_USHORT);
return;
}
// set the error
set_error (DTYPE_SIZE_HIGH, "set_ushort", "the variable size is too low to store unsigned short !");
return;
}
// set function for int value
void dtset_int ( dtype * var, int value )
{
int val = value;
// use internal set_object function to set the dtype data to value
// if error is not indicated, set the type and return
if ( !_dtset_obj ( var, &val, sizeof ( int ) ) ) {
set_type ( var, DTYPE_INT);
return;
}
// set the error
set_error (DTYPE_SIZE_HIGH, "set_int", "the variable size is too low to store int !");
return;
}
// set function for unsigned int
void dtset_uint ( dtype * var, unsigned int value )
{
unsigned int val = value;
// use internal set_object function to set the dtype data to value
// if error is not indicated, set the type and return
if ( !_dtset_obj ( var, &val, sizeof ( unsigned int ) ) ) {
set_type ( var, DTYPE_UINT);
return;
}
// set the error
set_error (DTYPE_SIZE_HIGH, "set_uint", "the variable size is too low to store unsigned int !");
return;
}
// set function for long value
void dtset_long ( dtype * var, long value )
{
long val = value;
// use internal set_object function to set the dtype data to value
// if error is not indicated, set the type and return
if ( !_dtset_obj ( var, &val, sizeof ( long ) ) ) {
set_type ( var, DTYPE_LONG);
return;
}
// set the error
set_error (DTYPE_SIZE_HIGH, "set_long", "the variable size is too low to store long !");
return;
}
// set function for unsigned long
void dtset_ulong ( dtype * var, unsigned long value )
{
unsigned long val = value;
// use internal set_object function to set the dtype data to value
// if error is not indicated, set the type and return
if ( !_dtset_obj ( var, &val, sizeof ( unsigned long ) ) ) {
set_type ( var, DTYPE_ULONG);
return;
}
// set the error
set_error (DTYPE_SIZE_HIGH, "set_ulong", "the variable size is too low to store unsigned long !");
return;
}
// set function for float
void dtset_float ( dtype * var, float value )
{
float val = value;
// use internal set_object function to set the dtype data to value
// if error is not indicated, set the type and return
if ( !_dtset_obj ( var, &val, sizeof ( float ) ) ) {
set_type ( var, DTYPE_FLOAT);
return;
}
// set the error
set_error (DTYPE_SIZE_HIGH, "set_float", "the variable size is too low to store float !");
return;
}
// set function for double
void dtset_double ( dtype * var, double value )
{
double val = value;
// use internal set_object function to set the dtype data to value
// if error is not indicated, set the type and return
if ( !_dtset_obj ( var, &val, sizeof ( double ) ) ) {
set_type ( var, DTYPE_DOUBLE);
return;
}
// set the error
set_error (DTYPE_SIZE_HIGH, "set_double", "the variable size is too low to store double !");
return;
}
// set function for char
void dtset_char ( dtype * var, char value )
{
char val = value;
// use internal set_object function to set the dtype data to value
// if error is not indicated, set the type and return
if ( !_dtset_obj ( var, &val, sizeof ( char ) ) ) {
set_type ( var, DTYPE_CHAR);
return;
}
// set the error
set_error (DTYPE_SIZE_HIGH, "set_char", "the variable size is too low to store char !");
}
// set function for strings ( char *)
void dtset_str ( dtype * var, char* value )
{
// use internal set_object function to set the dtype data to value
// if error is not indicated, set the type and return
if ( !_dtset_obj ( var,value,strlen ( value ) +1) ) {
set_type ( var, DTYPE_STR);
return;
}
// set the error
set_error (DTYPE_SIZE_HIGH, "set_str", "the variable size is too low to store string !");
}
// set function for custom objects / custom type variables
void dtset_obj ( dtype * var, void* obj, DTYPE_SIZE size )
{
// use internal set_object function to set the dtype data to value
// if error is not indicated, set the type and return
if ( !_dtset_obj ( var,obj,size ) ) {
set_type ( var, DTYPE_OBJECT);
return;
}
// set the error
set_error (DTYPE_SIZE_HIGH, "set_obj", "the variable size is too low to store the object !");
}
// ------- dtget_type(dtype) : returns the value as type, printing warning if needed ------
// get function to get boolean value
bool dtget_bool ( dtype * var )
{
// type check, if failed and DTYPE_WARN_OUT is set,
// print the warning, that we are trying to get it from another type!
if ( get_type ( var )!=DTYPE_BOOL && DTYPE_WARN_OUT ) {
printf ("\n[ Dtype warn: getting `bool` from another type: `%s` ]\n",get_stype ( var ) );
}
// return the value as a boolean
return *( ( bool*) ( var + DTYPE_MIN_MEM) );
}
// get function to get short value
short dtget_short ( dtype * var )
{
// type check, if failed and DTYPE_WARN_OUT is set,
// print the warning, that we are trying to get it from another type!
if ( get_type ( var )!=DTYPE_SHORT && DTYPE_WARN_OUT ) {
printf ("\n[ Dtype warn: getting `short` from another type: `%s` ]\n",get_stype ( var ) );
}
// return the value as short
return *( ( short*) ( var + DTYPE_MIN_MEM) );
}
// get function to get unsigned short value
unsigned short dtget_ushort ( dtype * var )
{
// type check, if failed and DTYPE_WARN_OUT is set,
// print the warning, that we are trying to get it from another type!
if ( get_type ( var )!=DTYPE_USHORT && DTYPE_WARN_OUT ) {
printf ("\n[ Dtype warn: getting `unsigned short` from another type: `%s` ]\n",get_stype ( var ) );
}
// return the value as unsigned short
return *( ( unsigned short *) ( var + DTYPE_MIN_MEM) );
}
// get function to get int
int dtget_int ( dtype * var )
{
// type check, if failed and DTYPE_WARN_OUT is set,
// print the warning, that we are trying to get it from another type!
if ( get_type ( var )!=DTYPE_INT && DTYPE_WARN_OUT ) {
printf ("\n[ Dtype warn: getting `int` from another type: `%s` ]\n",get_stype ( var ) );
}
// return the value as int
return *( ( int*) ( var + DTYPE_MIN_MEM) );
}
// get function to get unsigned int
unsigned int dtget_uint ( dtype * var )
{
// type check, if failed and DTYPE_WARN_OUT is set,
// print the warning, that we are trying to get it from another type!
if ( get_type ( var )!=DTYPE_UINT && DTYPE_WARN_OUT ) {
printf ("\n[ Dtype warn: getting `unsigned int` from another type: `%s` ]\n",get_stype ( var ) );
}
// return the value as unsigned int
return *( ( unsigned int*) ( var + DTYPE_MIN_MEM) );
}
// get function to get long
long dtget_long ( dtype * var )
{
// type check, if failed and DTYPE_WARN_OUT is set,
// print the warning, that we are trying to get it from another type!
if ( get_type ( var )!=DTYPE_LONG && DTYPE_WARN_OUT ) {
printf ("\n[ Dtype warn: getting `long` from another type: `%s` ]\n", get_stype ( var ) );
}
// return the value as long
return *( ( long*) ( var + DTYPE_MIN_MEM) );
}
// get function to get unsigned long
unsigned long dtget_ulong ( dtype * var )
{
// type check, if failed and DTYPE_WARN_OUT is set,
// print the warning, that we are trying to get it from another type!
if ( get_type ( var )!=DTYPE_ULONG && DTYPE_WARN_OUT ) {
printf ("\n[ Dtype warn: getting `unsigned long` from another type: `%s` ]\n", get_stype ( var ) );
}
// return the value as unsigned long
return *( ( unsigned long*) ( var + DTYPE_MIN_MEM) );
}
// get function to get float
float dtget_float ( dtype * var )
{
// type check, if failed and DTYPE_WARN_OUT is set,
// print the warning, that we are trying to get it from another type!
if ( get_type ( var )!=DTYPE_FLOAT && DTYPE_WARN_OUT ) {
printf ("\n[ Dtype warn: getting `float` from another type: `%s` ]\n", get_stype ( var ) );
}
// return the value as float
return *( ( float*) ( var + DTYPE_MIN_MEM) );
}
// get function to get double
double dtget_double ( dtype * var )
{
// type check, if failed and DTYPE_WARN_OUT is set,
// print the warning, that we are trying to get it from another type!
if ( get_type ( var )!=DTYPE_DOUBLE && DTYPE_WARN_OUT ) {
printf ("\n[ Dtype warn: getting `double` from another type: `%s` ]\n", get_stype ( var ) );
}
// return the value as double
return *( ( double*) ( var + DTYPE_MIN_MEM) );
}
// get function to get char
char dtget_char ( dtype * var )
{
// type check, if failed and DTYPE_WARN_OUT is set,
// print the warning, that we are trying to get it from another type!
if ( get_type ( var )!=DTYPE_CHAR && DTYPE_WARN_OUT ) {
printf ("\n[ Dtype warn: getting `char` from another type: `%s` ]\n", get_stype ( var ) );
}
// return value as char
return *( ( var + DTYPE_MIN_MEM) );
}
// get function to get string ( char *)
char * dtget_str ( dtype * var )
{
// type check, if failed and DTYPE_WARN_OUT is set,
// print the warning, that we are trying to get it from another type!
if ( get_type ( var )!=DTYPE_STR && DTYPE_WARN_OUT ) {
printf ("\n[ Dtype warn: getting `string` from another type: `%s` ]\n", get_stype ( var ) );
}
// return value as string ( char *)
return ( ( var + DTYPE_MIN_MEM) );
}
// get function to get void pointer of custom object ( void *)
void* dtget_object ( dtype * var )
{
// type check, if failed and DTYPE_WARN_OUT is set,
// print the warning, that we are trying to get it from another type!
if ( get_type ( var )!=DTYPE_OBJECT && DTYPE_WARN_OUT ) {
printf (
"\n[ Dtype warn: getting `object ( custom )` from another type: `%s` ]\n",
get_stype ( var )
);
}
// return the value as void pointer that can be changed
// ( void *)
return ( void*) ( var + DTYPE_MIN_MEM);
}
//function to print the value & return it's type
enum DTYPES_TYPES dt_print ( dtype * var )
{
switch ( get_type ( var ) )
{
// switch cases according to the type
// print them as required as their types and return it's type!
case DTYPE_NONE:
printf ("None"); return DTYPE_NONE;
case DTYPE_BOOL:
printf ( dtget_bool ( var ) ? "true" : "false"); return DTYPE_BOOL;
case DTYPE_SHORT:
printf ("%i",dtget_short ( var ) ); return DTYPE_SHORT;
case DTYPE_USHORT:
printf ("%d",( int ) dtget_ushort ( var ) );
return DTYPE_USHORT;
case DTYPE_INT:
printf ("%d", dtget_int ( var ) ); return DTYPE_INT;
case DTYPE_UINT:
printf ("%u", dtget_uint ( var ) ); return DTYPE_UINT;
case DTYPE_LONG:
printf ("%ld", dtget_long ( var ) ); return DTYPE_LONG;
case DTYPE_ULONG:
printf ("%lu", dtget_ulong ( var ) ); return DTYPE_ULONG;
case DTYPE_FLOAT:
printf ("%f", dtget_float ( var ) ); return DTYPE_FLOAT;
case DTYPE_DOUBLE:
printf ("%lf", dtget_double ( var ) ); return DTYPE_DOUBLE;
case DTYPE_CHAR:
printf ("%c", dtget_char ( var ) ); return DTYPE_CHAR;
case DTYPE_STR:
printf ("%s", dtget_str ( var ) ); return DTYPE_STR;
case DTYPE_OBJECT:
printf ("( custom object at %p )", (void*) var); return DTYPE_OBJECT;
case DTYPE_UNKNOWN:
printf ("unknown value"); return DTYPE_UNKNOWN;
default:
printf ("Invalid ( not initialized )"); return DTYPE_INVALID;
}
}
// -- dtin_type(dtype*) : returns the pointer to the data as type* and sets current type to type --
bool * dtin_bool ( dtype * var )
{
// set the type & send the pointer as ( bool * )
set_type ( var, DTYPE_BOOL);
return ( bool *) ( var + DTYPE_MIN_MEM);
}
short * dtin_short ( dtype * var )
{
// set the type & send the pointer as ( short * )
set_type ( var, DTYPE_SHORT);
return ( short *) ( var + DTYPE_MIN_MEM);
}
unsigned short * dtin_ushort ( dtype * var )
{
// set the type & send the pointer as ( unsigned short * )
set_type ( var, DTYPE_USHORT);
return ( unsigned short *) ( var + DTYPE_MIN_MEM);
}
int * dtin_int ( dtype * var )
{
// set the type & send the pointer as ( int * )
set_type ( var, DTYPE_INT);
return ( int*) ( var + DTYPE_MIN_MEM);
}
unsigned int * dtin_uint ( dtype * var )
{
// set the type & send the pointer as ( unsigned int * )
set_type ( var, DTYPE_UINT);
return ( unsigned int *) ( var + DTYPE_MIN_MEM);
}
long * dtin_long ( dtype * var )
{
// set the type & send the pointer as ( long * )
set_type ( var, DTYPE_LONG);
return ( long *) ( var + DTYPE_MIN_MEM);
}
unsigned long * dtin_ulong ( dtype * var )
{
// set the type & send the pointer as ( unsigned long * )
set_type ( var, DTYPE_ULONG);
return ( unsigned long *) ( var + DTYPE_MIN_MEM);
}
float * dtin_float ( dtype * var )
{
// set the type & send the pointer as ( float * )
set_type ( var, DTYPE_FLOAT);
return ( float *) ( var + DTYPE_MIN_MEM);
}
double * dtin_double ( dtype * var )
{
// set the type & send the pointer as ( double * )
set_type ( var, DTYPE_DOUBLE);
return ( double *) ( var + DTYPE_MIN_MEM);
}
char * dtin_char ( dtype * var )
{
// set the type & send the pointer as ( char * )
set_type ( var, DTYPE_CHAR);
return ( char *) ( var + DTYPE_MIN_MEM);
}
char * dtin_str ( dtype * var )
{
// set the type & send the pointer as ( char * )
set_type ( var, DTYPE_STR);
return ( char *) ( var + DTYPE_MIN_MEM);
}
// pack everything into dtypes
__dtypes_struct dtypes = {
// basic functions
dt_init, get_error, get_size, get_type, get_stype, set_type,
// set functions
dtset_none, dtset_bool, dtset_short, dtset_ushort, dtset_int, dtset_uint, dtset_long, dtset_ulong,
dtset_float, dtset_double, dtset_char, dtset_str, dtset_obj,
// get functions
dtget_bool, dtget_short, dtget_ushort, dtget_int, dtget_uint, dtget_long, dtget_ulong, dtget_float,
dtget_double, dtget_char, dtget_str, dtget_object,
// in functions
dtin_bool, dtin_short, dtin_ushort, dtin_int, dtin_uint, dtin_long, dtin_ulong, dtin_float,
dtin_double, dtin_char, dtin_str,
// printing function
dt_print
};
#include "dtype.h"
#include <stdio.h>
int main(void)
{
/*
Note :- printf("%d", dtypes.print(var)) kind of printing causes the variable to
be printed first, and then display the typecode of variable.
*/
// dtype var of 20 bytes
dtype var[20];
// initialize it with 20 bytes! [ it won't use more than size_of_bytes given in init ]
dtypes.init(var, 20);
// Example's of setting value!
// set_str set's the data of var to the string provided
dtypes.set_str(var, "Hello World!\n");
// dtypes.print() prints the content, and returns the typecode of that var!
// get_str_type returns the type in readable format than typecode
printf("Typecode: %d, Type: %s\n\n", dtypes.print(var), dtypes.get_str_type(var));
// store a boolean & print value
// set_bool set's data of the var to the boolean provided
dtypes.set_bool(var, 1);
printf("Value in boolean 1 : ");
dtypes.print(var); // true
printf("\n");
dtypes.set_bool(var, 0); // false
printf("Value in boolean 0 : ");
printf("\nTypecode: %d, Type: %s\n\n", dtypes.print(var), dtypes.get_str_type(var));
// store an int & print value
// set_int set's the data of var to the int provided
dtypes.set_int(var, -9856);
printf("\nTypecode: %d, Type: %s\n\n", dtypes.print(var), dtypes.get_str_type(var));
// set_uint set's the data of var to unsigned int provided
// let's try setting it to negative to see if it unsigned or not
dtypes.set_uint(var, -9856);
printf("\nTypecode: %d, Type: %s\n\n", dtypes.print(var), dtypes.get_str_type(var));
// copying from dtypes to other types!
unsigned int copied = dtypes.get_uint(var);
printf("copied from dtypes.get_uint value: %u\n", copied);
// copying from dtypes type mismatch, causes a warning to appear :) but copies it anyway
// type mismatch here is that we are trying to get integer value but stored value is of type unsigned int
int trytocopy = dtypes.get_int(var);
printf("tried to copy int from unsigned int stored in var, warning should be above ^^ ");
printf("\ntrytocopy value: %d!\n\n", trytocopy);
// to clear the variable
dtypes.set_none(var);
printf("After setting it to none, value: ");
printf("\nTypecode: %d, Type: %s\n\n", dtypes.print(var), dtypes.get_str_type(var));
return 0;
}
#include <stdio.h>
#include "dtype.h"
void scan_err(int scanf_output, dtype * var)
{
if(!scanf_output) {
printf("\n--- Invalid input or EOF ---\n");
// clear variable if input error
dtypes.set_none(var);
}
}
int main()
{
// dtype var of 20 bytes
dtype var[20];
// initialization
dtypes.init(var, 20);
printf("Enter integer: ");
// in_int returns an integer pointer to store/access value directly
scan_err(scanf("%d", dtypes.in_int(var)), var);
printf("Value: ");
printf("\nTypecode: %d, Type: %s\n\n", dtypes.print(var), dtypes.get_str_type(var));
printf("Enter string: ");
scan_err(scanf("%s", dtypes.in_str(var)), var);
printf("Value: ");
printf("\nTypecode: %d, Type: %s\n\n", dtypes.print(var), dtypes.get_str_type(var));
printf("Enter unsigned long value: ");
scan_err(scanf("%lu", dtypes.in_ulong(var)), var);
printf("Value: ");
printf("\nTypecode: %d, Type: %s\n\n", dtypes.print(var), dtypes.get_str_type(var));
return 0;
}