Basic Types

9 min read

4 min read

4 min read

4 min read

4 min read

4 min read

4 min read

4 min read

4 min read

Slice provides a number of built-in basic types, as shown in this table:

TypeRange of Mapped TypeSize of Mapped Type
bool
false or true
≥ 1 bit
byte
-128 to 127 or 0 to 255
≥ 8 bits
short
-2¹⁵ to 2¹⁵ - 1
≥ 16 bits
int
-2³¹ to 2³¹ - 1
≥ 32 bits
long
-2⁶³ to 2⁶³ - 1
≥ 64 bits
float
IEEE single-precision
≥ 32 bits
double
IEEE double-precision
≥ 64 bits
string
All Unicode characters
Variable-length

The range of byte depends on whether the language mapping uses a signed or an unsigned type for it.

All the basic types (except byte) are subject to changes in representation as they are transmitted between clients and servers. For example, a long value is byte-swapped when sent from a little-endian to a big-endian machine. However, these changes are transparent to the programmer and do exactly what is required.

Slice provides integer types short, int, and long, with 16-bit, 32-bit, and 64-bit ranges, respectively. Note that, on some architectures, any of these types may be mapped to a native type that is wider. Also note that no unsigned types are provided. (This choice was made because unsigned types are difficult to map into languages without native unsigned types, such as Java).

These types follow the IEEE specification for single- and double-precision floating-point representation [1]. If an implementation cannot support IEEE format floating-point values, the Ice runtime converts values into the native floating-point representation (possibly at a loss of precision or even magnitude, depending on the capabilities of the native floating-point format).

Slice strings use the Unicode character set and are encoded using UTF-8 when transmitted between clients and servers.

Boolean values can have only the values false and true. Language mappings use the corresponding native boolean type if one is available.

The Slice type byte is an (at least) 8-bit type that is guaranteed not to undergo any changes in representation as it is transmitted between address spaces. This guarantee permits exchange of binary data such that it is not tampered with in transit. All other Slice types are subject to changes in representation during transmission.

The built-in types are mapped to C++ types as shown in this table:

SliceC++
bool
bool
byte
std::uint8_t or std::byte
short
std::int16_t
int
std::int32_t
long
std::int64_t
float
float
double
double
string
std::string or std::string_view

A single byte is mapped to a std::uint8_t while a sequence<byte> is mapped to a std::vector<std::byte>.

A string is usually mapped to a C++ std::string. In particular, string fields, sequence elements, and dictionary keys and values, are always mapped to std::string. The mapping changes to std::string_view for individual string parameters that the application gives to Ice for marshaling, such as input parameters in proxy functions.

You can use a metadata directive, "cpp:type:wstring", to map strings to C++ std::wstring or std::wstring_view. For containers (such as interfaces or structures), the metadata directive applies to all strings within the type. A corresponding metadata directive, "cpp:type:string", can be used to selectively override the mapping defined by the enclosing container. For example:

Slice
["cpp:type:wstring"]
struct S1
{
string x; // Maps to std::wstring
["cpp:type:wstring"] string y; // Maps to std::wstring
["cpp:type:string"] string z; // Maps to std::string
}
struct S2
{
string x; // Maps to std::string
["cpp:type:string"] string y; // Maps to std::string
["cpp:type:wstring"] string z; // Maps to std::wstring
}

With these metadata directives, the strings are mapped as indicated by the comments.

On the wire, Ice transmits all strings as Unicode strings in UTF-8 encoding. For languages other than C++, Ice uses strings in their language-native Unicode representation and converts automatically to and from UTF-8 for transmission, so applications can transparently use characters from non-English alphabets.

However, for C++, how strings are represented inside a process depends on the platform as well as the mapping that is chosen for a particular string.

By default, the Ice runtime encodes strings as follows:

  • Narrow strings (that is, strings mapped to std::string) are presented to the application in UTF-8 encoding and, similarly, the application is expected to provide narrow strings in UTF-8 encoding to the Ice runtime for transmission.

    With this default behavior, the application code is responsible for converting between the native codeset for 8-bit characters and UTF-8. For example, if the native codeset is ISO Latin-1, the application is responsible for converting between UTF-8 and narrow (8-bit) characters in ISO Latin-1 encoding. The default behavior does not require the application to do anything if it only uses characters in the ASCII range. (This is because a string containing only characters in the (7-bit) ASCII range is also a valid UTF-8 string.)

  • Wide strings (that is, strings mapped to std::wstring) are automatically encoded as Unicode by the Ice runtime as appropriate for the platform. For example, for Windows, the Ice runtime converts between UTF-8 and UTF-16 in little-endian representation whereas, for Linux, the Ice run time converts between UTF-8 and UTF-32 in the endian-ness appropriate for the host CPU.

    With this default behavior, wide strings are transparently converted between their on-the-wire representation and their native C++ representation as appropriate, so application code need not do anything special.

The default behavior of the runtime can be changed by providing application-specific string converters. If you install such converters, all Slice strings will be passed to the appropriate converter when they are marshaled and unmarshaled. Therefore, the string converters allow you to convert all strings transparently into their native representation without having to insert explicit conversion calls whenever a string crosses a Slice interface boundary.

You can install string converters by calling Ice::setProcessStringConverter for the narrow string converter, and Ice::setProcessWstringConverter for the wide string converter. Any strings that use the default (std::string) mapping are passed through the specified narrow string converter and any strings that use the wide (std::wstring) mapping are passed through the specified wide string converter. Passing nullptr to one of these set functions resets the corresponding narrow or wide string converter to its default.

You can retrieve the previously installed string converters (or default string converters) with Ice::getProcessStringConverter and Ice::getProcessWstringConverter. The default narrow string converter is null, meaning Ice considers that all std::string are UTF-8. The default wide-string converter converts from UTF-16 or UTF-32 (depending on the size and endianness of the native wchar_t) to UTF-8.

The Slice built-in types are mapped to C# types as shown below:

SliceC#
bool
bool
byte
byte
short
short
int
int
long
long
float
float
double
double
string
string

The Slice built-in types are mapped to Java types as follows:

SliceJava
bool
boolean
byte
byte
short
short
int
int
long
long
float
float
double
double
string
String

The Slice built-in types are mapped to JavaScript and TypeScript types as follows:

SliceJavaScriptTypeScript
bool
Boolean
boolean
byte
Number
number
short
Number
number
int
Number
number
long
BigInt
bigint
float
Number
number
double
Number
number
string
String
string

The Slice built-in types are mapped to MATLAB types as shown in this table:

SliceMATLAB
bool
logical
byte
uint8
short
int16
int
int32
long
int64
float
single
double
double
string
character vector (1-by-n array of char), empty 1-by-0 character array for empty strings

PHP has a limited set of primitive types: boolean, integer, double, and string. The Slice built-in types are mapped to PHP types as shown in the table below:

SlicePHP
bool
true or false
byte
integer
short
integer
int
integer
long
integer
float
double
double
double
string
string

PHP's integer type may not accommodate the range of values supported by Slice's long type, therefore long values that are outside this range are mapped as strings. Scripts must be prepared to receive an integer or string from any operation that returns a long value.

The Slice built-in types are mapped to Python types as shown in this table:

SlicePython
bool
bool
short
int
int
int
long
int
float
float
double
float
string
str

Although Python supports arbitrary precision in its integer types, the Ice runtime validates integer values to ensure they have valid ranges for their declared Slice types.

The Slice built-in types are mapped to Ruby types as shown in this table:

SliceRuby
bool
true or false
byte
Fixnum
short
Fixnum
int
Fixnum or Bignum
long
Fixnum or Bignum
float
Float
double
Float
string
String

Although Ruby supports arbitrary precision in its integer types, the Ice runtime validates integer values to ensure they have valid ranges for their declared Slice types.

The Slice built-in types are mapped to Swift types as shown below:

SliceSwift
bool
Bool
byte
UInt8
short
Int16
int
Int32
long
Int64
float
Float
double
Double
string
String
  1. Institute of Electrical and Electronics Engineers. 1985. IEEE 754-1985 Standard for Binary Floating-Point Arithmetic. Piscataway, NJ: Institute of Electrical and Electronic Engineers.