Skip to main content
Skip table of contents

Slice Metadata Directives

Overview

Slice has the concept of a metadata directive. For example:

SLICE
["java:type:java.util.LinkedList<Integer>"] sequence<int> IntSeq;

A metadata directive can appear as a prefix to any Slice definition. Metadata directives appear in a pair of square brackets and contain one or more string literals separated by commas. For example, the following is a syntactically valid metadata directive containing two strings:

SLICE
["a", "b"] interface Example {}

Metadata directives are not part of the Slice language per se: the presence of a metadata directive has no effect on the client-server contract, that is, metadata directives do not change the Slice type system in any way. Instead, metadata directives are targeted at specific back-ends, such as the code generator for a particular language mapping. In the preceding example, the java: prefix indicates that the directive is targeted at the Slice to Java compiler.

Metadata directives permit you to provide supplementary information that does not change the Slice types being defined, but somehow influences how the compiler will generate code for these definitions. For example, a metadata directive java:type:java.util.LinkedList<T> instructs the Slice to Java compiler to map a sequence to a linked list instead of an array (which is the default).

Metadata directives are also used to create skeletons that support Asynchronous Method Dispatch (AMD) in some languages.

Apart from metadata directives that are attached to a specific definition, there are also file metadata directives. For example:

SLICE
[["cpp:dll-export:WIDGET_API"]]

Note that a file metadata directive is enclosed by double square brackets, whereas a local metadata directive (one that is attached to a specific definition) is enclosed by single square brackets. File metadata directives are used to pass instructions that affect the entire Slice file. File metadata directives must precede any definitions in a file (but can appear following any #include directives).

We describe below the metadata directives you can use.

General Metadata Directives

amd

This directive applies to interfaces and operations. It enables code generation for asynchronous method dispatch. (See Operations for details).

deprecated[:message]
deprecate[:message]

This directive allows you to emit a deprecation warning for Slice constructs.

format

This directive defines the encoding format used for any classes or exceptions marshaled as the arguments or results of an operation. The tag can be applied to an interface, which affects all of its operations, or to individual operations. Legal values for the tag are format:sliced, format:compact, and format:default. A tag specified for an operation overrides any setting applied to its enclosing interface. The Ice.Default.SlicedFormat property defines the behavior when no tag is present.

marshaled-result

This directive applies to operations and changes the return type of mapped skeleton methods in C++, C#, and Java. It has no effect on the client-side mapping.

With this directive, the mapped skeleton method returns a “marshaled result” struct or class that marshals the return value and out parameters immediately in its constructor. This allows you to perform the marshaling in a thread-safe manner, typically while holding a mutex lock.

For example:

CODE
sequence<int> IntSeq;
sequence<IntSeq> IntIntSeq;
sequence<string> StringSeq;

class Grid
{
    StringSeq xLabels;
    StringSeq yLabels;
    IntIntSeq values;
}
  
interface GridIntf
{
   // We want to marshal the returned Grid object within a lock,
   // and return a consistent object not affected by concurrent calls to
   // clearValues.
   ["marshaled-result"] 
   ["cs:identifier:GetGrid"]
   Grid getGrid();
   
   void clearValues();
}

The mapped skeleton member function for getGrid is:

CPP
GetGridMarshaledResult getGrid(const Ice::Current& current) = 0;

where GetGridMarshaledResult is a generated class with a constructor that accepts a parameter for the return value, followed by Current:

CPP
// Generated server-side code
class GetGridMarshaledResult : public Ice::MarshaledResult
{
public:
    // Marshals returnValue immediately.
    GetGridMarshaledResult(const GridPtr& returnValue, const Ice::Current& current);
};

A typical implementation of the getGridoperation in your servant would be:

CPP
GetGridMarshaledResult
GridServant::getGrid(const Ice::Current& current)
{
   lock_guard lock(_mutex);
   // marshal _grid data member within synchronization
   return GetGridMarshaledResult{_grid, current};
}

A marshaled-result instance is specific to a request. Do not cache a marshaled result and return it for another request.

suppress-warning

This file directive allows to suppress Slice compiler warnings. It applies to all definitions in the Slice file that includes this directive. If one or more categories are specified (for example "suppress-warning:invalid-metadata" or "suppress-warning:deprecated, invalid-metadata") only warnings matching these categories will be suppressed, otherwise all warnings are suppressed. The categories are described in the following table:

Suppress Warning Category

Description

all

Suppress all Slice compiler warnings. Equivalent to [["suppress-warning"]].

deprecated

Suppress warnings related to deprecated features.

invalid-comment

Suppress warnings related to invalid doc-comments.

Language-Specific Metadata Directives

The metadata directives for C++ uses the cpp prefix.

cpp:array

This directive applies to sequence parameters in operations. It directs the Slice compiler to map these parameters to pairs of pointers.

cpp:const

This directive applies to operations. It directs the Slice compiler to create a const pure virtual member function for the skeleton class.

The generated skeleton code calls servant member functions using a shared_ptr<non-const-T>. Adding this const only affects your own servant implementation code.

cpp:custom-print

This directive applies to enumerations, structs, classes and exceptions. It tells the Slice compiler that you want to implement your own “custom print” for this type, and not rely on the compiler-generated print implementation.

For an enum E, the Slice compiler generates a declaration for std::ostream& operator<<(std::ostream&, E)in the enclosing namespace, but does not implement this operator.

For a struct S, the Slice compiler generates a declaration for std::ostream& operator<<(std::ostream&, const S&)in the enclosing namespace, but does not implement this operator.

For a class or exception C, the Slice compiler generates a declaration for the member function void ice_print(std::ostream& os) const override in the mapped C++ class, but does not implement this member function.

cpp:dll-export:SYMBOL

This file directive applies to all definitions in a Slice file.

Use SYMBOL to control the export and import of symbols from DLLs on Windows and shared libraries on other platforms. This option allows you to export symbols from the generated code, and place such generated code in a DLL (on Windows) or shared library (on other platforms). As an example, compiling a Slice file Widget.ice with:

SLICE
[["cpp:dll-export:WIDGET_API"]]

results in the following additional code being generated into Widget.h:

CPP
#ifndef WIDGET_API
#   if defined(ICE_STATIC_LIBS)
#       define WIDGET_API /**/
#   ifdef WIDGET_API_EXPORTS
#       define WIDGET_API ICE_DECLSPEC_EXPORT
#   else
#       define WIDGET_API ICE_DECLSPEC_IMPORT
#   endif
#endif

The generated code also includes the provided SYMBOL name (WIDGET_API in our example) in the declaration of classes and functions that need to be exported (when building a DLL or shared library) or imported (when using such library).  

ICE_DECLSPEC_EXPORT and ICE_DECLSPEC_IMPORT are macros that expand to compiler-specific attributes. For example, for Visual Studio, they are defined as:

CPP
#if defined(_MSC_VER)
#   define ICE_DECLSPEC_EXPORT __declspec(dllexport)
#   define ICE_DECLSPEC_IMPORT __declspec(dllimport)

With GCC and clang, they are defined as:

CPP
#elif defined(__GNUC__) || defined(__clang__)
#   define ICE_DECLSPEC_EXPORT __attribute__((visibility ("default")))
#   define ICE_DECLSPEC_IMPORT __attribute__((visibility ("default")))

The generated .cpp file (Widget.cpp in our example) defines SYMBOL_EXPORTS; this way, you don't need to do anything special when compiling generated files. 

cpp:doxygen:include:c++-header

This file directive instructs the Slice compiler to generate a doc-comment with @headerfile and the specified C++ header for all generated C++ classes.

cpp:header-ext:c++-ext

This file directive allows you to use a file extension for C++ header files other than the default .h extension.

cpp:identifier:c++-identifier

This directive applies to all Slice constructs, and instructs the Slice compiler to use the specified c++-identifier.

For example:

SLICE
struct Descriptor
{
    ["cpp:identifier:blueprint"]
    string template;
}

The cpp:identifierdirective ensures the field template is mapped to blueprint in C++. We can’t use the default mapping (template) since it’s a C++ keyword.

cpp:ice_print

This directive applies to exceptions. It is a deprecated alias for cpp:custom-print.

cpp:include:c++-header

This file directive allows you inject additional #include directives into the generated C++ header file. This is useful for custom types.

cpp:source-ext:c++-ext

This file directive allows you to use a file extension for C++ source files other than the default .cpp extension.

cpp:source-include:c++-header

This file directive allows you inject additional #include directives into the generated C++ source file. This is required to make forward declared types visible to the source files.

cpp:type:c++-type

This directive applies to sequences and dictionaries. It directs the Slice compiler to map the Slice type or parameter to the provided C++ type. 

cpp:type:string and cpp:type:wstring

These directives apply to fields of type string as well as to containers, such as structures, classes and exceptions. String fields map by default to std::string. You can use the cpp:type:wstring metadata to cause a string field (or all string fields in a structure, class or exception) to map to std::wstring instead. Use the cpp:type:string metadata to force string fields to use the default mapping regardless of any enclosing metadata.

SLICE
module A
{
    ["cpp:type:wstring"] struct Struct1
    {
        string s1; // Maps to std::wstring
        ["cpp:type:string"] string s2; // Maps to std::string
    }
}

cpp:view-type:c++-view-type

This directive applies to sequence parameters. It directs the Slice compiler to map this parameter to the provided C++ type when this parameter does not need to hold any memory, for example when mapping an in-parameter to a proxy function.

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.