I have a C enum with around 50 values (they are error codes). Besides the first value, the numbering is kept automatic.
typedef enum {
MY_STATUS_OK = 0,
MY_STATUS_ERROR_UNKNOWN,
MY_STATUS_ERROR_A,
MY_STATUS_ERROR_B,
/* ... */
MY_STATUS_ERROR_LAST
} my_status_t;
I do get an enum description in the HTML, but it doesn't show the explicit value, only the enum values' name.
I want to document the association between hard value and enum value name. Right now when I get an error value, I need to manually count the index in the enum to find out what it means.
Related
I just looked for the below questions and did not find a complete answer. So this is what I found out
how can I get an enum value by index
how can I get the index position of an enum value
for the following enum
enum Status {
none,
running,
stopped,
paused
}
Status.values[1] provides Status.running
Status.running.index provides 1
if you have a variable Status myStatus; you can substitute Status.running with myStatus
I have a problem with converting a string variable to TObject.
I have a query that returns two columns to me. In the first column I have varchar values that I translate into strings, and in the second column I have int values.
I want to fill a ComboBox in this way with these values:
cbx1-> AddItem (DataSet1->DataSet->Fields->Field[0]->AsString, (TObject *) (int) DataSet1->DataSet->Fields->Field[1];
As I refer to the second value which is int type, I receive some bushes, e.g., xD, etc.
By trying to convert this value to string, eg:
String temp = IntToStr (DataSet1->DataSet->Fields->Field[1]);
cbx1-> AddItem (DataSet1->DataSet->Fields->Field[0]->AsString, (TObject *) temp;
I receive an error message:
cannot cast from 'AnsiString' to 'TObject'
I do not know what further I can do to convert this value.
You cannot cast an AnsiString value to a TObject* pointer. You can only cast an integer value, or a pointer value, to a TObject* pointer. AnsiString is neither of those.
You are not retrieving the int value from the 2nd field correctly anyway. Field[1] is a pointer to an actual TField object in the Fields collection. That pointer is what you are trying to store in your ComboBox, NOT the int value that the TField represents.
You need to call Fields[1]->AsInteger to get the int value of the 2nd field, similar to how you use Fields[0]->AsString to get the string value of the 1st field:
cbx1->AddItem(
DataSet1->DataSet->Fields->Field[0]->AsString,
(TObject*) DataSet1->DataSet->Fields->Field[1]->AsInteger
// in C++, using reinterpret_cast is preferred over C-style casting:
// reinterpret_cast<TObject*>(DataSet1->DataSet->Fields->Field[1]->AsInteger)
);
This is no different than the code in your previous question:
cbx1->AddItem("one",(TObject*)1);
You are now just placing the literals "one" and 1 with runtime variables of equivalent types.
I'm new to golang and am trying to understand a code example of type wrapping for the "non-atomic" type time.Time.
The type extension in question is from the Go client for GDAX on github, go-coinbase-exchange project.
The expected behavior would be for Time variables from the project (coinbase.Time), which are of type Time time.Time (as defined in the project's time.go file) to behave something like the following example for extending the "atomic" type int (from blog.riff.org in that they might follow a kind of "inheritance" from the base type for functions like Time.format (from golang's standard implementation of time:
package main
import "fmt"
type Int int
func (i Int) Add(j Int) Int {
return i + j
}
func main() {
i := Int(5)
j := Int(6)
fmt.Println(i.Add(j))
fmt.Println(i.Add(j) + 12)
}
But if I modify the code example from the project's List Account Ledger example found in Readme.md to include a print function which might otherwise give me a human-readable view of the CreatedAt struct variables (as follows), I get a compiler error saying that "type coinbase.Time has no field or method Format":
for _, e := range ledger {
print("Entry Creation: ")
fmt.Printf(e.CreatedAt.Format("2006-01-02 15:04:05.999999+00"))
}
The expected behavior inside the for loop would be for it to print the ledger entries in a human-readable format. I can get the contents of the structs, but I'm not really sure how to then use the resulting wall, ext and loc members.
For example, inserting fmt.Printf("%#v", e.CreatedAt) into the for loop gives me a representation of the time that looks something like this:
coinbase.Time{wall:0x3015a123, ext:63612345678, loc:(*time.Location)(nil)}
{806986000 63638738354 <nil>}
I can also see that wall is of type uint64, that ext is of type int64 and that loc is just GMT/UTC=0 by formatting the variable as a string because fmt.Printf("%s", e.CreatedAt) gives me output which is similar to the following:
{%!s(uint64=712345678) %!s(int64=63612345678) %!s(*time.Location=<nil>)}
It seems like I'm missing something. I've requested further information through issues tab on github, but maybe this is a nube question. So I'm not sure how quick the response time would be, and I'm interested in the more general case for extending non-atomic types in go.
Named types do not inherit any methods from the underlying type (indeed there is no inheritance at all in Go); you must cast to the underlying type to call any methods from that type:
(time.Time(e.CreatedAt)).Format("2006-01-02 15:04:05.999999+00")
Is there any way to pass the value of an enum by name from the commandline? Rather what's the cleanest solution?
I tried the below,
typedef enum int unsigned { white, black, red } colour_e;
class house;
rand colour_e colour;
string n_colour = "white";
constraint c_colour {
colour.name() == n_colour;
}
endclass: house
program top;
house paradise;
initial begin
paradise = new();
void'($value$plusargs("colour=%0s", paradise.n_colour));
if (!paradise.randomize())
$display("not randomized");
else
$display("paradise.colour = %s",paradise.colour);
end
endprogram: top
I would want to pass something like this +colour=black. so that the paradise.colour is assigned black.
vcs cribbed for using enum.name() in the constraints.
below is the error.
Error-[NYI-CSTR-SYS-FTC] NYI constraint: sys function calls
T-enum_1.sv, 9 $unit, "this.colour.name" System function calls are
not yet implemented in constraints. Remove the function call or if
possible replace it with an integral state variable assigned in
pre_randomize().
while Riviera cried as below
ERROR VCP7734 "Type of 'this.colour.name()' is not allowed in a
constraint block. Only integral types are allowed in a constraint
block." "design.sv" 9 1 ERROR VCP7734 "Type of 'n_colour' is not
allowed in a constraint block. Only integral types are allowed in a
constraint block." "design.sv" 9 1 WARNING VCP7114 "STRING value
expected for format specifier %s as parameter
paradise.colour." "testbench.sv" 13 54
which brings the question to me, does everything in the contraint block has to be of integral type (just like we cannot declare a string as rand variable)?
ANyone wants to play around the code please have a look at the code at EDA playground here
Use uvm_enum_wrapper class to do the conversion from string to corresponding enum value. It is a template class wrapper defined in uvm_globals.svh (part of UVM 1.2) and you can use it as follows:
typedef enum {white, black, red} colour_e;
typedef uvm_enum_wrapper#(colour_e) colour_wrapper;
string colour_str;
void'($value$plusargs("colour=%0s", colour_str));
colour_wrapper::from_name(colour_str, paradize.n_colour);
The wrapper class uvm_enum_wrapper works by traversing the enum entries and creating an assoc array for a enum[string] map for the given enum type (supplied as template parameter). For more details take a look at the documentation.
There is another solution for the same. If you are not using UVM 1.2 version then there is like you can take string as an input argument and convert that string argument into int type. After that you can directly cast int to enum type by $cast.
Because there is no way to convert string to enum type (except UVM 1.2) so you have to add one extra step for the same.
module Test;
typedef enum {black,red,blue} color_e; //enum declaration
color_e color; //type of enum
string cmd_str; //Commandline string input
int cmd_int; //Input string is first converted into int
initial
begin
$value$plusargs("enum_c=%0s",cmd_str); //Take input argument as string it may be 0,1 or 2
cmd_int=cmd_str.atoi(); //Now convert that string argument into int type
$cast(color,cmd_int); //Casting int to enum type
$display("Value of color is --> %p",color); //Display value of enum
end
endmodule
I wonder whether it is possible to add/append another item to an existing enum type (part of a framework)?
Something like this: We have the enum type
typedef enum {
UIModalTransitionStyleCoverVertical = 0,
UIModalTransitionStyleFlipHorizontal,
UIModalTransitionStyleCrossDissolve,
UIModalTransitionStylePartialCurl,
} UIModalTransitionStyle;
Now I want to append or add to this set an item like UIModalTransitionStyleCoverVerticalFlipped.
Can something like this be accomplished?
You can force new element to have the same type as the enum, but you can't extend it in a subclass.
header file:
extern const UIModalTransitionStyle UIModalTransitionStyleCoverVerticalFlipped;
implementation file:
const UIModalTransitionStyle UIModalTransitionStyleCoverVerticalFlipped = 10;
Make sure to give some space in case the framework is extended, so that you don't have conflicts. This is a bit of a hack, but it will get rid of compiler errors and warnings.
To do it, you have to modify the original type definition to include the new value:
typedef enum {
UIModalTransitionStyleCoverVertical = 0,
UIModalTransitionStyleFlipHorizontal,
UIModalTransitionStyleCrossDissolve,
UIModalTransitionStylePartialCurl,
UIModalTransitionStyleCoverVerticalFlipped
} UIModalTransitionStyle;
Otherwise, you can take a chance on its not working, and define it separately:
typedef enum {
UIModalTransitionStyleCoverVertical = 0,
UIModalTransitionStyleFlipHorizontal,
UIModalTransitionStyleCrossDissolve,
UIModalTransitionStylePartialCurl,
} UIModalTransitionStyle;
typedef enum {
UIModalTransitionStyleCoverVerticalFlipped =
UIModalTransitionStylePartialCurl + 1
} ExtendedUIModalTransitionStyle;
A variable that could hold the original enumeration will usually also work perfectly fine when/if you assign the new value as well (in a typical case, it'll just be an int) -- but it's not guaranteed. At least in theory, the implementation can/could assign few enough bits to hold that enumeration that it adding more values this way wouldn't work. It could also do range checking so assigning any out of range value wouldn't be allowed. Neither of these is at all common, so from a practical viewpoint it's probably not a problem -- but from a theoretical viewpoint, nothing really guarantees that code like this will work.
Maybe this can help you:
typedef NS_ENUM(NSInteger, BaseType) {
BaseTypeCase1,
BaseTypeCase2,
BaseTypeSize
};
typedef NS_ENUM(NSInteger, SubType) {
SubTypeCase1 = BaseTypeSize,
SubTypeCase2
};
Now you can switch on SubType knowing the values are unique.
If you don't have access to BaseType, you could set SubTypeCase1 to BaseType's last item + 1.
Downside is, you can't declare a method that takes a SubType and pass to it a BaseType without getting a compiler warning. So you need to declare your methods to take NSIntegers in order silence that warning.
Also, it feels weird when you need to declare a parameter of SubType and be able to pass in a BaseType.
To do this you have to update the Enum declaration to include UIModalTransitionStyleCoverVerticalFlipped this values as well
typedef enum {
UIModalTransitionStyleCoverVertical = 0,
UIModalTransitionStyleFlipHorizontal,
UIModalTransitionStyleCrossDissolve,
UIModalTransitionStylePartialCurl,
UIModalTransitionStyleCoverVerticalFlipped
} UIModalTransitionStyle;
so UIModalTransitionStyleCoverVerticalFlipped will be equivalent to integer constant 4
whereever you use any string constant from Enum dec. corresponding constant value get replaced so it is used to constraint the variable to hold only specified set of values only(i.e. 0 to 4) in above mentioned case