LibraryLink Utilities  3.0.1
Modern C++ wrapper over LibraryLink and WSTP
LLU::WSStream Class Reference

Description

Wrapper class over WSTP with a stream-like interface.

WSStream resides in LLU namespace, whereas other WSTP-related classes can be found in LLU::WS namespace.

Template Parameters
EncodingIn- default encoding to use when reading strings from WSTP
EncodingOut- default encoding to use when writing strings to WSTP

#include <WSStream.hpp>

Public Types

using StreamToken = WSStream &(*)(WSStream &)
 Type of elements that can be sent via WSTP with no arguments, for example WS::Flush. More...
 
using BidirStreamToken = WSStream &(*)(WSStream &, WS::Direction)
 Type of elements that can be either sent or received via WSTP with no arguments, for example WS::Rule. More...
 
using LoopbackData = std::pair< std::string, WSLINK >
 Type of data stored on the stack to facilitate sending expressions of a priori unknown length. More...
 

Public Member Functions

 WSStream (WSLINK mlp)
 Constructs new WSStream. More...
 
 WSStream (WSLINK mlp, int argc)
 Constructs new WSStream and checks whether there is a list of argc arguments on the LinkObject waiting to be read. More...
 
 WSStream (WSLINK mlp, const std::string &head, int argc)
 Constructs new WSStream and checks whether there is a function with head head and argc arguments on the LinkObject waiting to be read. More...
 
 ~WSStream ()=default
 Default destructor. More...
 
WSLINK & get () noexcept
 Returns a reference to underlying low-level WSTP handle. More...
 
template<typename Iterator , typename = enable_if_input_iterator<Iterator>>
void sendRange (Iterator begin, Iterator end)
 Sends any range as List. More...
 
template<typename Iterator , typename = enable_if_input_iterator<Iterator>>
void sendRange (Iterator begin, Iterator end, const std::string &head)
 Sends a range of elements as top-level expression with arbitrary head. More...
 
WSStreamoperator<< (StreamToken f)
 Sends a stream token via WSTP. More...
 
WSStreamoperator<< (BidirStreamToken f)
 Sends a bidirectional stream token via WSTP. More...
 
WSStreamoperator<< (const WS::Symbol &s)
 Sends a top-level symbol via WSTP. More...
 
WSStreamoperator<< (const WS::Function &f)
 Sends a top-level function via WSTP, function arguments should be sent immediately after. More...
 
WSStreamoperator<< (const WS::Missing &f)
 Sends a top-level expression of the form Missing["reason"]. More...
 
WSStreamoperator<< (const WS::BeginExpr &expr)
 Starts sending a new expression where the number of arguments is not known a priori. More...
 
WSStreamoperator<< (const WS::DropExpr &expr)
 Drops current expression that was initiated with BeginExpr. More...
 
WSStreamoperator<< (const WS::EndExpr &expr)
 Ends current expression that was initiated with BeginExpr, prepends the head from BeginExpr and sends everything to the "parent" link. More...
 
WSStreamoperator<< (bool b)
 Sends a boolean value via WSTP, it is translated to True or False in Mathematica. More...
 
WSStreamoperator<< (mint i)
 Sends a mint value. More...
 
template<typename T >
WSStreamoperator<< (const WS::ArrayData< T > &a)
 Sends a WSTP array. More...
 
template<typename T >
WSStreamoperator<< (const WS::ListData< T > &l)
 Sends a WSTP list. More...
 
template<typename T , typename D >
WSStreamoperator<< (const std::unique_ptr< T, D > &p)
 Sends an object owned by unique pointer. More...
 
template<typename T >
WSStreamoperator<< (const std::vector< T > &l)
 Sends a std::vector via WSTP, it is interpreted as a List in Mathematica. More...
 
template<WS::Encoding E>
WSStreamoperator<< (const WS::StringData< E > &s)
 Sends a WSTP string. More...
 
template<WS::Encoding E, typename T >
WSStreamoperator<< (const WS::PutAs< E, T > &wrp)
 Sends all strings within a given object using specified character encoding. More...
 
template<typename T >
WSStreamoperator<< (const std::basic_string< T > &s)
 Sends std::basic_string. More...
 
template<typename T , std::size_t N, typename = std::enable_if_t<WS::StringTypeQ<T>>>
WSStreamoperator<< (const T(&s)[N])
 Sends a character array (or a string literal) More...
 
WSStreamoperator<< (const char *s)
 Sends a C-string. More...
 
template<typename K , typename V >
WSStreamoperator<< (const std::map< K, V > &map)
 Sends a std::map via WSTP, it is translated to an Association in Mathematica. More...
 
template<typename T , typename = std::enable_if_t<std::is_arithmetic_v<T>>>
WSStreamoperator<< (T value)
 Sends a scalar value (int, float, double, etc) if it is supported by WSTP If you need to send value of type not supported by WSTP (like unsigned int) you must either explicitly cast or provide your own overload. More...
 
template<typename Container , typename = std::void_t< decltype(std::declval<Container>().begin(), std::declval<Container>().end(), std::declval<Container>().size())>>
WSStreamoperator<< (const Container &c)
 Sends any container (a class with begin(), end() and size()) as List. More...
 
WSStreamoperator>> (BidirStreamToken f)
 Receives a bidirectional stream token via WSTP. More...
 
WSStreamoperator>> (const WS::Symbol &s)
 Receives a symbol from WSTP. More...
 
WSStreamoperator>> (WS::Symbol &s)
 Receives a symbol from WSTP. More...
 
WSStreamoperator>> (const WS::Function &f)
 Receives a function from WSTP. More...
 
WSStreamoperator>> (WS::Function &f)
 Receives a function from WSTP. More...
 
WSStreamoperator>> (bool &b)
 Receives a True or False symbol from Mathematica and converts it to bool. More...
 
WSStreamoperator>> (mint &i)
 Receives a mint value. More...
 
template<typename T >
WSStreamoperator>> (WS::ArrayData< T > &a)
 Receives a WSTP array. More...
 
template<typename T >
WSStreamoperator>> (WS::ListData< T > &l)
 Receives a WSTP list. More...
 
template<typename T >
WSStreamoperator>> (std::vector< T > &l)
 Receives a List from WSTP and assigns it to std::vector. More...
 
template<WS::Encoding E = EncodingIn>
WSStreamoperator>> (WS::StringData< E > &s)
 Receives a WSTP string. More...
 
template<typename T >
WSStreamoperator>> (std::basic_string< T > &s)
 Receives std::basic_string. More...
 
template<WS::Encoding E, typename T >
WSStreamoperator>> (WS::GetAs< E, T > wrp)
 Receives a value of type T. More...
 
template<typename K , typename V >
WSStreamoperator>> (std::map< K, V > &map)
 Receives a std::map via WSTP. More...
 
template<typename T , typename = std::enable_if_t<std::is_arithmetic_v<T>>>
WSStreamoperator>> (T &value)
 Receives a scalar value (int, float, double, etc) if it is supported by WSTP If you need to receive value of type not supported by WSTP (like unsigned int) you must either explicitly cast or provide your own overload. More...
 

Type aliases documentation

◆ BidirStreamToken

Type of elements that can be either sent or received via WSTP with no arguments, for example WS::Rule.

◆ LoopbackData

using LLU::WSStream::LoopbackData = std::pair<std::string, WSLINK>

Type of data stored on the stack to facilitate sending expressions of a priori unknown length.

◆ StreamToken

Type of elements that can be sent via WSTP with no arguments, for example WS::Flush.

Constructor & Destructor Documentation

◆ WSStream() [1/3]

LLU::WSStream::WSStream ( WSLINK  mlp)
explicit

Constructs new WSStream.

Parameters
[in]mlp- low-level object of type WSLINK received from LibraryLink

◆ WSStream() [2/3]

LLU::WSStream::WSStream ( WSLINK  mlp,
int  argc 
)

Constructs new WSStream and checks whether there is a list of argc arguments on the LinkObject waiting to be read.

Parameters
[in]mlp- low-level object of type WSLINK received from LibraryLink
[in]argc- expected number of arguments

◆ WSStream() [3/3]

LLU::WSStream::WSStream ( WSLINK  mlp,
const std::string &  head,
int  argc 
)

Constructs new WSStream and checks whether there is a function with head head and argc arguments on the LinkObject waiting to be read.

Parameters
[in]mlp- low-level object of type WSLINK received from LibraryLink\
[in]head- expected head of expression on the Link
[in]argc- expected number of arguments
Exceptions
seeWSStream::testHead(const std::string&, int);
Note
arguments passed to the library function will almost always be wrapped in a List, so if not sure pass "List" as head

◆ ~WSStream()

LLU::WSStream::~WSStream ( )
default

Default destructor.

Member Function Documentation

◆ get()

WSLINK& LLU::WSStream::get ( )
inlinenoexcept

Returns a reference to underlying low-level WSTP handle.

◆ operator<<() [1/22]

WSStream& LLU::WSStream::operator<< ( BidirStreamToken  f)

Sends a bidirectional stream token via WSTP.

Parameters
[in]f- an element that can be either sent or received via WSTP with no arguments, for example WS::Rule

◆ operator<<() [2/22]

WSStream& LLU::WSStream::operator<< ( bool  b)

Sends a boolean value via WSTP, it is translated to True or False in Mathematica.

Parameters
[in]b- a boolean value
Exceptions
ErrorName::WSPutSymbolError

◆ operator<<() [3/22]

WSStream& LLU::WSStream::operator<< ( const char *  s)

Sends a C-string.

Parameters
[in]s- C-string to be sent
See also
http://reference.wolfram.com/language/guide/WSTPCFunctionsForExchangingStrings.html
Exceptions
ErrorName::WSPutStringError

◆ operator<<() [4/22]

template<typename Container , typename = std::void_t< decltype(std::declval<Container>().begin(), std::declval<Container>().end(), std::declval<Container>().size())>>
WSStream& LLU::WSStream::operator<< ( const Container &  c)
inline

Sends any container (a class with begin(), end() and size()) as List.

Template Parameters
Container- type that is a collection of some elements
Parameters
[in]c- container to be sent
Exceptions
ErrorName::WSPutContainerError
Note
Size() is not technically necessary, but needed for performance reason. Most STL containers have size() anyway.

◆ operator<<() [5/22]

template<typename T >
WSStream& LLU::WSStream::operator<< ( const std::basic_string< T > &  s)

Sends std::basic_string.

Template Parameters
T- string character type supported in any of WSPut*String
Parameters
[in]s- std::basic_string<T> to be sent
See also
http://reference.wolfram.com/language/guide/WSTPCFunctionsForExchangingStrings.html
Exceptions
ErrorName::WSPutStringError

◆ operator<<() [6/22]

template<typename K , typename V >
WSStream& LLU::WSStream::operator<< ( const std::map< K, V > &  map)

Sends a std::map via WSTP, it is translated to an Association in Mathematica.

Template Parameters
K- map key type, must be supported in WSStream
V- map value type, must be supported in WSStream
Parameters
[in]map- map to be sent as Association
Exceptions
ErrorName::WSPutFunctionErrorplus whatever can be thrown sending keys and values

◆ operator<<() [7/22]

template<typename T , typename D >
WSStream& LLU::WSStream::operator<< ( const std::unique_ptr< T, D > &  p)

Sends an object owned by unique pointer.

Template Parameters
T- list element type
D- destructor type, not really relevant
Parameters
[in]p- pointer to the object to be sent

◆ operator<<() [8/22]

template<typename T >
WSStream& LLU::WSStream::operator<< ( const std::vector< T > &  l)

Sends a std::vector via WSTP, it is interpreted as a List in Mathematica.

Template Parameters
T- vector element type (types supported in WSPut*List will be handled more efficiently)
Parameters
[in]l- std::vector to be sent
Exceptions
ErrorName::WSPutListError

◆ operator<<() [9/22]

template<typename T , std::size_t N, typename = std::enable_if_t<WS::StringTypeQ<T>>>
WSStream& LLU::WSStream::operator<< ( const T(&)  s[N])

Sends a character array (or a string literal)

Template Parameters
T- character type supported in any of WSPut*String
N- length of character array
Parameters
[in]s- character array to be sent as String
See also
http://reference.wolfram.com/language/guide/WSTPCFunctionsForExchangingStrings.html
Exceptions
ErrorName::WSPutStringError

◆ operator<<() [10/22]

template<typename T >
WSStream& LLU::WSStream::operator<< ( const WS::ArrayData< T > &  a)

Sends a WSTP array.

Template Parameters
T- array element type
Parameters
[in]a- ArrayData to be sent
See also
WS::ArrayData<T>
http://reference.wolfram.com/language/guide/WSTPCFunctionsForExchangingMultidimensionalArrays.html
Exceptions
ErrorName::WSPutArrayError

◆ operator<<() [11/22]

WSStream& LLU::WSStream::operator<< ( const WS::BeginExpr expr)

Starts sending a new expression where the number of arguments is not known a priori.

Parameters
[in]expr- object of class BeginExpr that stores expression head as string

◆ operator<<() [12/22]

WSStream& LLU::WSStream::operator<< ( const WS::DropExpr expr)

Drops current expression that was initiated with BeginExpr.

Parameters
[in]expr- object of class DropExpr

◆ operator<<() [13/22]

WSStream& LLU::WSStream::operator<< ( const WS::EndExpr expr)

Ends current expression that was initiated with BeginExpr, prepends the head from BeginExpr and sends everything to the "parent" link.

Parameters
[in]expr- object of class EndExpr

◆ operator<<() [14/22]

WSStream& LLU::WSStream::operator<< ( const WS::Function f)

Sends a top-level function via WSTP, function arguments should be sent immediately after.

Parameters
[in]f- a function
See also
WS::Function
Exceptions
ErrorName::WSPutFunctionError

◆ operator<<() [15/22]

template<typename T >
WSStream& LLU::WSStream::operator<< ( const WS::ListData< T > &  l)

Sends a WSTP list.

Template Parameters
T- list element type
Parameters
[in]l- ListData to be sent
See also
WS::ListData<T>
http://reference.wolfram.com/language/guide/WSTPCFunctionsForExchangingLists.html
Exceptions
ErrorName::WSPutListError

◆ operator<<() [16/22]

WSStream& LLU::WSStream::operator<< ( const WS::Missing f)

Sends a top-level expression of the form Missing["reason"].

Parameters
[in]f- WS::Missing object with a reason
See also
WS::Missing
Exceptions
ErrorName::WSPutFunctionError

◆ operator<<() [17/22]

template<WS::Encoding E, typename T >
WSStream& LLU::WSStream::operator<< ( const WS::PutAs< E, T > &  wrp)

Sends all strings within a given object using specified character encoding.

Normally, when you send a string WSStream chooses the appropriate WSTP function based on the EncodingOut template parameter. Sometimes you may want to locally override the output encoding and you can do this by wrapping the object with WS::PutAs<desired encoding, wrapped type> (you can use WS::putAs function to construct WS::PutAs object without having to explicitly specify the second template parameter).

WSStream<WS::Encoding::UTF8> mls { mlink }; // By default use UTF8
std::vector<std::string> vecOfExpr = ....; // This is a vector of serialized Mathematica expressions,
ml << WS::putAs<WS::Encoding::Native>(vecOfExpr); // it should be sent with Native encoding
Parameters
[in]wrp- object to be sent

◆ operator<<() [18/22]

template<WS::Encoding E>
WSStream& LLU::WSStream::operator<< ( const WS::StringData< E > &  s)

Sends a WSTP string.

Template Parameters
E- encoding of the string (it determines which function from WSPut*String family to use)
Parameters
[in]s- WS::StringData to be sent
See also
WS::StringData<E>
http://reference.wolfram.com/language/guide/WSTPCFunctionsForExchangingStrings.html
Exceptions
ErrorName::WSPutStringError

◆ operator<<() [19/22]

WSStream& LLU::WSStream::operator<< ( const WS::Symbol s)

Sends a top-level symbol via WSTP.

Parameters
[in]s- a symbol
See also
WS::Symbol
Exceptions
ErrorName::WSPutSymbolError

◆ operator<<() [20/22]

WSStream& LLU::WSStream::operator<< ( mint  i)

Sends a mint value.

Parameters
[in]i- a mint value
Exceptions
ErrorName::WSPutScalarError

◆ operator<<() [21/22]

WSStream& LLU::WSStream::operator<< ( StreamToken  f)

Sends a stream token via WSTP.

Parameters
[in]f- a stream token, i.e. an element that can be sent via WSTP with no arguments, for example WS::Flush

◆ operator<<() [22/22]

template<typename T , typename = std::enable_if_t<std::is_arithmetic_v<T>>>
WSStream& LLU::WSStream::operator<< ( value)

Sends a scalar value (int, float, double, etc) if it is supported by WSTP If you need to send value of type not supported by WSTP (like unsigned int) you must either explicitly cast or provide your own overload.

Template Parameters
T- scalar type
Parameters
[in]value- numeric value to be sent
Exceptions
ErrorName::WSPutScalarError

◆ operator>>() [1/15]

WSStream& LLU::WSStream::operator>> ( BidirStreamToken  f)

Receives a bidirectional stream token via WSTP.

Parameters
[in]f- an element that can be either sent or received via WSTP with no arguments, for example WS::Rule

◆ operator>>() [2/15]

WSStream& LLU::WSStream::operator>> ( bool &  b)

Receives a True or False symbol from Mathematica and converts it to bool.

Parameters
[out]b- argument to which the boolean received from WSTP will be assigned
Exceptions
ErrorName::WSGetSymbolError,ErrorName::WSWrongSymbolForBool

◆ operator>>() [3/15]

WSStream& LLU::WSStream::operator>> ( const WS::Function f)

Receives a function from WSTP.

Parameter f must have head and argument count specified and they need to match the head and argument count that was read from WSTP

Parameters
[in]f- a function with head and argument count specified
See also
WS::Function
Exceptions
ErrorName::WSGetFunctionError,ErrorName::WSTestHeadError

◆ operator>>() [4/15]

WSStream& LLU::WSStream::operator>> ( const WS::Symbol s)

Receives a symbol from WSTP.

Parameter s must have head specified and it has to match the head that was read from WSTP

Parameters
[in]s- a symbol
See also
WS::Symbol
Exceptions
ErrorName::WSGetSymbolError,ErrorName::WSTestHeadError

◆ operator>>() [5/15]

WSStream& LLU::WSStream::operator>> ( mint &  i)

Receives a mint value.

Parameters
[in]i- argument to which a mint value will be assigned
Note
It actually reads an wsint64 and casts to mint, as mint is not natively supported by WSTP.

◆ operator>>() [6/15]

template<typename T >
WSStream& LLU::WSStream::operator>> ( std::basic_string< T > &  s)

Receives std::basic_string.

Template Parameters
T- string character type supported in any of WSGet*String
Parameters
[out]s- argument to which the std::basic_string<T> received from WSTP will be assigned
See also
http://reference.wolfram.com/language/guide/WSTPCFunctionsForExchangingStrings.html
Exceptions
ErrorName::WSGetStringError
Note
std::string is just std::basic_string<char>

◆ operator>>() [7/15]

template<typename K , typename V >
WSStream& LLU::WSStream::operator>> ( std::map< K, V > &  map)

Receives a std::map via WSTP.

Template Parameters
K- map key type, must be supported in WSStream
V- map value type, must be supported in WSStream
Parameters
[out]map- argument to which the std::map received from WSTP will be assigned
Exceptions
ErrorName::WSGetFunctionErrorplus whatever can be thrown receiving keys and values
Note
The top-level Association must have all values of the same type because this is how std::map works

◆ operator>>() [8/15]

template<typename T >
WSStream& LLU::WSStream::operator>> ( std::vector< T > &  l)

Receives a List from WSTP and assigns it to std::vector.

Template Parameters
T- vector element type (types supported in WSGet*List will be handled more efficiently)
Parameters
[out]l- argument to which the List received from WSTP will be assigned
Exceptions
ErrorName::WSGetListError

◆ operator>>() [9/15]

template<typename T , typename = std::enable_if_t<std::is_arithmetic_v<T>>>
WSStream& LLU::WSStream::operator>> ( T &  value)

Receives a scalar value (int, float, double, etc) if it is supported by WSTP If you need to receive value of type not supported by WSTP (like unsigned int) you must either explicitly cast or provide your own overload.

Template Parameters
T- scalar type
Parameters
[out]value- argument to which the value received from WSTP will be assigned
Exceptions
ErrorName::WSGetScalarError

◆ operator>>() [10/15]

template<typename T >
WSStream& LLU::WSStream::operator>> ( WS::ArrayData< T > &  a)

Receives a WSTP array.

Template Parameters
T- array element type
Parameters
[out]a- argument to which the WS::ArrayData received from WSTP will be assigned
See also
WS::ArrayData<T>
http://reference.wolfram.com/language/guide/WSTPCFunctionsForExchangingMultidimensionalArrays.html
Exceptions
ErrorName::WSGetArrayError

◆ operator>>() [11/15]

WSStream& LLU::WSStream::operator>> ( WS::Function f)

Receives a function from WSTP.

If the parameter f has head or argument count set, than it has to match the head or argument count that was read from WSTP

Parameters
[in,out]f- a function which may have head or argument count specified
See also
WS::Function
Exceptions
ErrorName::WSGetFunctionError,ErrorName::WSTestHeadError

◆ operator>>() [12/15]

template<WS::Encoding E, typename T >
WSStream& LLU::WSStream::operator>> ( WS::GetAs< E, T >  wrp)

Receives a value of type T.

Template Parameters
E- encoding to be used when reading value from WSTP
T- value type
Parameters
wrp- reference to object of type T wrapped in WS::GetAs structure
Note
There is a utility function WS::getAs for easier creation of WS::GetAs objects

◆ operator>>() [13/15]

template<typename T >
WSStream& LLU::WSStream::operator>> ( WS::ListData< T > &  l)

Receives a WSTP list.

Template Parameters
T- list element type
Parameters
[out]l- argument to which the WS::ListData received from WSTP will be assigned
See also
WS::ListData<T>
http://reference.wolfram.com/language/guide/WSTPCFunctionsForExchangingLists.html
Exceptions
ErrorName::WSGetListError

◆ operator>>() [14/15]

template<WS::Encoding E = EncodingIn>
WSStream& LLU::WSStream::operator>> ( WS::StringData< E > &  s)

Receives a WSTP string.

Template Parameters
T- string character type
Parameters
[out]s- argument to which the WS::StringData received from WSTP will be assigned
See also
WS::StringData<T>
http://reference.wolfram.com/language/guide/WSTPCFunctionsForExchangingStrings.html
Exceptions
ErrorName::WSGetStringError

◆ operator>>() [15/15]

WSStream& LLU::WSStream::operator>> ( WS::Symbol s)

Receives a symbol from WSTP.

If the parameter s has head specified, then it has to match the head that was read from WSTP, otherwise the head read from WSTP will be assigned to s

Parameters
[in,out]s- a symbol
See also
WS::Symbol
Exceptions
ErrorName::WSGetSymbolError,ErrorName::WSTestHeadError

◆ sendRange() [1/2]

template<typename Iterator , typename = enable_if_input_iterator<Iterator>>
void LLU::WSStream::sendRange ( Iterator  begin,
Iterator  end 
)

Sends any range as List.

Template Parameters
InputIterator- type that is an iterator
Parameters
[in]begin- iterator to the first element of the range
[in]end- iterator past the last element of the range

◆ sendRange() [2/2]

template<typename Iterator , typename = enable_if_input_iterator<Iterator>>
void LLU::WSStream::sendRange ( Iterator  begin,
Iterator  end,
const std::string &  head 
)

Sends a range of elements as top-level expression with arbitrary head.

Template Parameters
InputIterator- type that is an iterator
Parameters
[in]begin- iterator to the first element of the range
[in]end- iterator past the last element of the range
[in]head- head of the top-level expression