V4 Requirements for Standard Types

From EPICSWIKI

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:

  1. Must provide a default constructor so instances can be created without any initialization parameters.
  2. 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.
      • ...
  3. Strings must be assignable (if the target string is mutable).
  4. Assignment never changes the target string's buffer type or capacity, it just copies character data from the source to the target string.
  5. 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.
  6. The EpicsString class must implement a comparison function that works between segmented and non-segmented strings
  7. 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.
  8. 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.
  9. 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