The list of supported types by datastore doesn't contain pointer types (https://cloud.google.com/appengine/docs/go/datastore/reference).
How then can I represent a value that can and sometimes should be nil?
For example in the following structure I need the DailyValuePercent to be nilable to explicitly say that the value is missing.
type NutritionFact struct {
Name string `datastore:",noindex" json:"name"`
DailyValuePercent int `datastore:",noindex" json:"dailyValuePercent"`
}
Since I can't use *int as the field type for datastore then how to represent an optional value?
Either store your ints as strings (with empty string => no value) or use a composite type like:
type NillableInt struct {
i int
isNil bool // or isNotNil bool if you want different default semantics
}
Adapt to your performance vs. memory usage requirements.
If you want your code to deal with int pointers but persist nil values in the datastore, define your struct like this:
type NutritionFact struct {
Name string `datastore:",noindex" json:"name"`
DailyValuePercent int `datastore:"-"`
}
And implement the PropertyLoadSaver interface where you will save/load an int value and a isNil boolean.
Related
I want to define an API that accepts a (type, value) pair and performs some operation on them.
typedef enum {
TTL_ENTRY = 1,
ACCESS_ENTRY = 2
}type_t;
typedef struct {
type_t type;
uint32 value;
}type_val_t;
int entries_add(size_t count, type_val_t *type_val);
Each type has it's own range of possible values.
TTL_ENTRY's value can be a uint32 with any value.
ACCESS_ENTRY's value should accept only values from the enum:
typedef enum {
STATE_NONE = 0,
STATE_DROP,
STATE_PATH
/* ... */
}state_t;
Is there a way to make this API more clear about which value should pair with which type?
Or somehow bind a value type for each type from type_t?
I thought converting value type from a uint32 into a union of possible values, like so:
typedef union {
uint32 ttl_bitmap;
state_t state;
}value_t;
typedef struct {
type_t type;
value_t value;
}type_val_t;
But even when using this kind of type it is not 100% clear which value should be coupled with which type.
I think based on your limited example that using a union for value_t is probably a good idea.
About the best you can do beyond that, in C, is to name the fields in the union directly after the enums which select those fields so the correspondence is clear to any user of these data structures.
For your example this might mean you should make value_t look more like this:
typedef union {
uint32 ttl_entry;
state_t access_entry;
} value_t;
So when choosing your type selector enum identifiers you might consider how they could also be used as field names.
You may then also want to write a macro or set of macros for accessing each field based on the enum value.
There may be other ways to design your API and data structures in a more C-friendly way, but you would have to describe your larger problem (probably in another question) to get more guidance.
I am trying to implement a generic and dynamic set data structure, yet I am struggling with the generic part. I understand that it is essentially an array of type pointer-to-void, but I just do not know how to enable the user to choose the type of the elements to add to a particular set. I have searched this site thoroughly, yet there does not seem to be an answer to my question. The dynamic_set type is defined as follows:
typedef struct
{
int size;
int capacity;
void ** data;
} dynamic_set;
I need to know the type of the elements in order to be able to typecast the pointers and eventually dereference them so that I can check if the sets are compatible for a union, to decide on what type of function to apply to return an aggregate value, etc. Should I include another member in the above structure which represents the type of the elements within that set, like an enum? Any help is vastly appreciated!
I can propose you to use pointers-to-functions to provide operations over the pointer stored values:
struct DynamicSet
{
void** Items;
size_t Size;
size_t Capacity;
int (*compare)(void*, void*);
};
DynamicSet* DynamicSet_Create(size_t capacity,
int (*compare)(void*, void*));
int CompareInts(void* left, void* right)
{
int leftInt = *((int*)left);
...
}
DynamicSet* dynamicSet = DynamicSet_Create(100, CompareInts);
To use it with other type you just write another Comparator function.
But if you want more type safety and more convenient signatures for you functions you may try to emulate C++ templates with macro substitution.
Let's say I have a function..
void * getValue(...);
Is there a way that I check for the return type of a call to getValue(...) ?
I plan on using a void* method such as getValue() in a program and the process of my program will be dependent on the return type of getValue().
Is it possible to check for return type?
You may want to return a structure instead
enum valuetype {PCHAR, PSHORT, PINT, PLONG, PLLONG, PFLOAT, PDOUBLE, PLDOUBLE};
struct sometype {
enum valuetype vt;
void *value;
}
struct sometype getValue(...);
I'm afraid there's no way you can tell exactly what's stored in a (void *) pointer. If you want my advise, change your code and use proper typed pointers
No - C does not tag values with their type, so the information is not available.
Possible alternatives include adding an out parameter to the function to indicate the type, or making/using a variant struct that includes both the value and an enum indicating its type.
Often stacks in C are dependent upon datatype used to declare them. For example,
int arr[5]; //creates an integer array of size 5 for stack use
char arr[5]; //creates a character array of size 5 for stack use
are both limited to holding integer and character datatypes respectively and presumes that the programmer knows what data is generated during the runtime. What if I want a stack which can hold any datatype?
I initially thought of implementing it as a union, but the approach is not only difficult but also flawed. Any other suggestions?
I would use a structure like this:
struct THolder
{
int dataType; // this is a value representing the type
void *val; // this is the value
};
Then use an array of THolder to store your values.
This is really just a variant of Pablo Santa Cruz' answer, but I think it looks neater:
typedef enum { integer, real, other } type_t;
typedef struct {
type_t type;
union {
int normal_int; /* valid when type == integer */
double large_float; /* valid when type == real */
void * other; /* valid when type == other */
} content;
} stack_data_t;
You still need to use some way to explicitly set the type of data stored in each element, there is no easy way around that.
You could look into preprocessor magic relying on the compiler-dependent typeof keyword to do that automagically, but that will probably not do anything but ruin the portability.
Some people have suggested a void* member. In addition to that solution I'd like to offer an alternative (assuming your stack is a linked list of heap-allocated structures):
struct stack_node
{
struct stack_node *next;
char data[];
};
The data[] is a C99 construct. data must be the last member; this takes advantage of the fact that we can stuff arbitrary quantities after the address of the struct. If you're using non-C99 compiler you might have to do some sketchy trick like declare it as data[0].
Then you can do something like this:
struct stack_node*
allocate_stack_node(size_t extra_size)
{
return malloc(sizeof(struct stack_node) + extra_size);
}
/* In some other function... */
struct stack_node *ptr = allocate_stack_node(sizeof(int));
int *p = (int*)ptr->data;
If this looks ugly and hacky, it is... But the advantage here is that you still get the generic goodness without introducing more indirection (thus slightly quicker access times for ptr->data than if it were void* pointing to a different location from the structure.)
Update: I'd also like to point out that the code sample I give may have problems if your machine happens to have different alignment requirements for int than char. This is meant as an illustrative example; YMMV.
You could use macros and a "container" type to reduce "type" from being per-element, to whole-container. (C99 code below)
#define GENERIC_STACK(name, type, typeid, elements) \
struct name##_stack { \
unsigned int TypeID; \
type Data[elements]; \
} name = { .TypeID = typeid }
Of course, your "TypeID" would have to allow every possible agreed-upon type you expect; might be a problem if you intend to use whole structs or other user-defined types.
I realize having a uniquely named struct type for every variable is odd and probably not useful... oops.
I created an library that works for any data type:
List new_list(int,int);
creates new list eg:
List list=new_list(TYPE_INT,sizeof(int));
//This will create an list of integers
Error append(List*,void*);
appends an element to the list. *Append accpts two pointers as an argument, if you want to store pointer to the list don't pass the pointer by pointer
eg:
//using the int list from above
int a=5;
Error err;
err=append(&list,&a)
//for an list of pointers
List listptr=new_list(TYPE_CUSTOM,sizeof(int*));
int num=7;
int *ptr=#
append(&listptr,ptr);
//for list of structs
struct Foo
{
int num;
float *ptr;
};
List list=new_list(TYPE_CUSTOM,sizeof(struct Foo));
struct Foo x;
x.num=9;
x.ptr=NULL;
append(&list,&x);
Error get(List*,int);
Gets data at index specified. When called list's current poiter will point to the data.
eg:
List list=new_list(TYPE_INT,sizeof(int));
int i;
for(i=1;i<=10;i++)
append(&list,&i);
//This will print the element at index 2
get(&list,2);
printf("%d",*(int*)list.current);
Error pop(List*,int);
Pops and element from the specified index
eg:
List list=new_list(TYPE_INT,sizeof(int));
int i;
for(i=1;i<=10;i++)
append(&list,&i);
//element in the index 2 will be deleted,
//the current pointer will point to a location that has a copy of the data
pop(&list,2);
printf("%d",*(int*)list.current);
//To use the list as stack, pop at index list.len-1
pop(&list,list.len-1);
//To use the list as queue, pop at index 0
pop(&list,0);
Error merge(List ,List);
Merges two list of same type. If types are different will return a error message in the Error object it returns;
eg:
//Merge two elements of type int
//List 2 will come after list 1
Error err;
err=merge(&list1,&list2);
Iterator get_iterator(List*);
Get an iterator to an list. when initialized will have a pointer to the first element of the list.
eg:
Iterator ite=get_iterator(&list);
Error next(Iterator*);
Get the next element of the list.
eg:
//How to iterate an list of integers
Iterator itr;
for(itr=get_iterator(&list); ite.content!=NULL; next(ite))
printf("%d",*(int*)ite.content);
https://github.com/malayh/C-List
I have list of 5 elements. I get first element of this list. How can i kwno what's the data type of this element char* or int*?
Thank you
You can't.
Either use type-specific lists (one list for your char-pointers, one list for your ints) or use a structure or union to store both types of values with a field that indicates the type, like this:
#define TYPE_INT 1
#define TYPE_STRING 2
struct MyValue
{
int type; // TYPE_INT or TYPE_STRING
union
{
char *str;
int i;
} value;
};
And store this struct into your list.
If C++ is an option, consider using std::list to store type specific data, or if this is not possible, define a class similar to the struct above in which you shield the different data types, like this (not including error checking on the type):
class MyValue
{
public:
enum ValueType
{
TYPE_NONE;
TYPE_INT,
TYPE_STRING
};
MyValue() : m_type(TYPE_NONE) {}
MyValue(char *s) : m_type(TYPE_STRING), m_value.str(s) {}
MyValue(int i) : m_type(TYPE_INT), m_value.int(i) {}
ValueType getType() const {return m_type;}
const char *getString() const {return m_value.str;}
int getInt() const {return m_value.int;}
private:
ValueType m_type;
union InternalValue
{
char *str;
int i;
};
InternalValue m_value;
};
In C, there is no (portable) way to find out if all you have is a void*. So you have to keep track about it yourself, when you store the elements into the list. Another possibility is to use type-specific lists instead of a generic void* list.
What do you mean by "list" here?
Is it:
sometype* lst;
i.e. an array, or:
node* lst;
A linked list?
In the first case, sometype defines the type of elements in the array, unless it's some kind of a void* which means that the compiler doesn't know the type but the programmer (hopefully) does. In the second case you should look into the definition of node, it should contain data with typing information of some sort (and the void* argument from above applies).