Difference between revisions of "V4 Requirements for Standard Types"
Line 131: | Line 131: | ||
epicsInt16 index; | epicsInt16 index; | ||
} | } | ||
Revision as of 15:56, 6 June 2005
The purpose of this page is to discuss the requirements for the standard data types that will be used and supported throughout EPICS V4.
Numeric Types
epicsBoolean
A boolean type.
typedef bool epicsBoolean;
epicsInt16
A signed 16-bit integer type.
typedef short epicsInt16;
epicsInt32
A signed 32-bit integer type.
typedef int epicsInt32;
epicsInt64
A signed 64-bit integer type.
typedef long long epicsInt64;
On some architectures, this may need to be defined as:
typedef long epicsInt64;
epicsFloat32
A 32-bit IEEE floating-point numeric type.
typedef float epicsFloat32;
epicsFloat64
A 64-bit IEEE floating-point numeric type.
typedef double epicsFloat64
Character Types
epicsOctet
An 8-bit character type. This is not intended to be used for numeric operations, just for storing and manipulating raw data bytes, including use for Unicode/UTF-8 encoded strings.
typedef char epicsOctet;
- Q: Should we make this explicitly an unsigned char? It could resolve some portability issues, but probably would create others.
EpicsString
A Unicode/UTF-8 encoded string.
Requirements for EpicsString
To be adopted widely, an EpicsString should be usable like any regular C++ type, although we don't need it to be anywhere near as rich as the C++ std::string class. This is my list of requirements for EpicsString:
- Must provide a default constructor so instances can be created without any initialization parameters.
- Must be able to support different kinds of underlying buffer storage, such as:
- Read only - immutable, used to hold string literals.
- The constructor EpicsString(const char *) should create a string that just stores the given pointer as its buffer.
- Attempts to modify the string will probably throw an exception.
- On some architectures overwriting a string literal causes a SEGV, so this protection is worth doing to avoid crashes.
- Fixed capacity - mutable and contiguous, for things like record names that don't get changed after being set.
- The character buffer is intended to be allocated just once.
- The string contents can be modified, but cannot be extended beyond the allocated capacity.
- Variable capacity - mutable and segmented, for strings that might change quite often.
- Uses a freelist to manage its buffer as a series of string segments.
- ...
- Read only - immutable, used to hold string literals.
- Strings must be assignable (if the target string is mutable).
- Assignment never changes the target string's buffer type or capacity, it just copies character data from the source to the target string.
- We need to provide access to the underlying character data in a unified way that will work for all buffer types.
- We've designed an API that works for segmented strings, which the other types can also use.
- The EpicsString class must implement a comparison function that works between segmented and non-segmented strings
- Strings should also be comparable using operator == and operator !=.
- However these operators will be non-member functions that takes two const EpicsString& parameters; this permits the LHS to undergo type conversion from a literal.
- We're probably not going to provide less-than or greater-than comparisons because the correct ordering of characters is language specific.
- However this makes it impossible to do binary searches or create tree structures.
- We might want to revisit this point later.
- This list not yet complete...
The above requirements ensure that the following code snippets (or something very like these) will do what it looks like they should do:
EpicsString hello = "World!"; // create a readonly string EpicsString msg(...); // create a variable length string msg = hello; // copy the readonly data if (msg == hello) { ... } // compare strings if ("hello" != hello) { ... } // implicit type conversion
Composite Types
EpicsEnum
A 16-bit index value, with an interface to convert between choice strings and their index values. Here's a proposal:
class EpicsEnumChoices { public: virtual EpicsEnumChoices *duplicate() const = 0; virtual void release() = 0; virtual epicsInt16 nChoices() const = 0; virtual epicsInt16 index(const EpicsString &choice) const = 0; virtual void choice(epicsInt16 index, EpicsString &choice) const = 0; } class EpicsEnum { public: enum {invalid = -1}; EpicsEnum(); EpicsEnum(const EpicsEnum &e); EpicsEnum(EpicsEnumChoices *choices); EpicsEnum(EpicsEnumChoices *choices, epicsInt16 index); virtual ~EpicsEnum(); EpicsEnum& operator=(const EpicsEnum &rhs); virtual void choices(EpicsEnumChoices *pchoices); EpicsEnumChoices *choices() const { return pchoices; } epicsInt16 nChoices() const { return pchoices ? pchoices->nChoices() : 0; } epicsInt16 get() const { return index; } virtual void get(EpicsString &choice) const; virtual void put(epicsInt16 index); virtual void put(const EpicsString &choice); protected: EpicsEnumChoices *pchoices; epicsInt16 index; }