Turi Create  4.0
turi::flexible_type Class Reference

#include <core/data/flexible_type/flexible_type.hpp>

Public Member Functions

 flexible_type () noexcept
 
template<typename T >
 flexible_type (std::initializer_list< T > &&list)
 
 ~flexible_type ()
 
 flexible_type (const flexible_type &other) noexcept
 
 flexible_type (flexible_type &other) noexcept
 
template<typename T >
 flexible_type (const T &other, typename std::enable_if< has_direct_conversion_to_flexible_type< T >::value >::type *=nullptr)
 
 flexible_type (flexible_type &&other) noexcept
 
 flexible_type (const flexible_type &&other) noexcept
 
template<typename T >
 flexible_type (T &&other, typename std::enable_if< has_direct_conversion_to_flexible_type< typename std::remove_reference< T >::type >::value >::type *=nullptr)
 
flexible_typesoft_assign (const flexible_type &other)
 
flexible_typeoperator= (const flexible_type &other) noexcept
 
flexible_typeoperator= (flexible_type &other) noexcept
 
flexible_typeoperator= (flexible_type &&other) noexcept
 
flexible_typeoperator= (const flexible_type &&other) noexcept
 
template<typename T >
std::enable_if< has_direct_conversion_to_flexible_type< T >::value, flexible_type & >::type operator= (const T &other)
 
flexible_typeoperator= (flex_undefined other)
 
template<typename T >
std::enable_if< has_direct_conversion_to_flexible_type< typename std::remove_reference< T >::type >::value, flexible_type & >::type operator= (T &&other)
 
void reset (flex_type_enum target_type)
 
void reset ()
 
flexible_typeset_date_time_from_timestamp_and_offset (const std::pair< flex_int, int32_t > &datetime, const int32_t microsecond=0)
 
std::pair< flex_int, int32_t > get_date_time_as_timestamp_and_offset () const
 
int32_t get_date_time_microsecond () const
 
void swap (flexible_type &b)
 
template<typename T >
T & mutable_get ()
 
template<typename T >
const T & get () const
 
template<typename T >
T & reinterpret_mutable_get ()
 
template<typename T >
const T & reinterpret_get () const
 
flex_type_enum get_type () const
 
std::type_index type () const
 
size_t which () const
 
size_t hash () const
 
uint128_t hash128 () const
 
bool is_zero () const
 
bool is_na () const
 
bool contains_na () const
 
template<typename Visitor >
auto apply_mutating_visitor (Visitor visitor) -> decltype(visitor(prototype_flex_int))
 
template<typename Visitor >
auto apply_visitor (Visitor visitor) const -> decltype(visitor(prototype_flex_int))
 
template<typename Visitor >
auto apply_mutating_visitor (Visitor visitor, const flexible_type &other) -> decltype(visitor(prototype_flex_int, flex_int()))
 
template<typename Visitor >
auto apply_visitor (Visitor visitor, const flexible_type &other) const -> decltype(visitor(prototype_flex_int, flex_int()))
 
template<class T , typename std::enable_if< std::is_integral< T >::value >::type * = (void*)NULL>
FLEX_ALWAYS_INLINE_FLATTEN operator T () const
 Implicit cast to integral types.
 
template<class T , typename std::enable_if< std::is_floating_point< T >::value >::type * = (void*)NULL>
FLEX_ALWAYS_INLINE_FLATTEN operator T () const
 Implicit cast to floating point types.
 
 operator flex_string () const
 
 operator flex_vec () const
 
 operator flex_nd_vec () const
 
 operator flex_list () const
 
 operator flex_dict () const
 
 operator flex_date_time () const
 
 operator flex_image () const
 
flexible_type operator- () const
 
flexible_typeoperator+= (const flexible_type &other)
 
flexible_typeoperator-= (const flexible_type &other)
 
flexible_typeoperator/= (const flexible_type &other)
 
flexible_typeoperator%= (const flexible_type &other)
 
flexible_typeoperator*= (const flexible_type &other)
 
flexible_type operator+ (const flexible_type &other) const
 
flexible_type operator- (const flexible_type &other) const
 
flexible_type operator* (const flexible_type &other) const
 
flexible_type operator/ (const flexible_type &other) const
 
flexible_type operator% (const flexible_type &other) const
 
bool operator== (const flexible_type &other) const
 
bool operator!= (const flexible_type &other) const
 
bool approx_equal (const flexible_type &other) const
 
bool identical (const flexible_type &other) const
 
bool operator< (const flexible_type &other) const
 
bool operator> (const flexible_type &other) const
 
bool operator<= (const flexible_type &other) const
 
bool operator>= (const flexible_type &other) const
 
flexible_typeoperator++ ()
 Preincrement. Equivalent to (*this)+=1.
 
flexible_type operator++ (int)
 Preincrement. Equivalent to (*this)+=1, returning a copy of the previous value.
 
flexible_typeoperator-- ()
 Preincrement. Equivalent to (*this)-=1.
 
flexible_type operator-- (int)
 Preincrement. Equivalent to (*this)-=1, returning a copy of the previous value.
 
template<typename T >
flexible_type operator- (const T &other) const
 
template<typename T >
flexible_type operator+ (const T &other) const
 
template<typename T >
flexible_type operator/ (const T &other) const
 
template<typename T >
flexible_type operator% (const T &other) const
 
template<typename T >
flexible_type operator* (const T &other) const
 
template<typename T >
bool operator== (const T &other) const
 
template<typename T >
bool operator!= (const T &other) const
 
template<typename T >
bool operator< (const T &other) const
 
template<typename T >
bool operator> (const T &other) const
 
template<typename T >
bool operator<= (const T &other) const
 
template<typename T >
bool operator>= (const T &other) const
 
flex_floatoperator[] (size_t index)
 
const flex_floatoperator[] (size_t index) const
 
flexible_typearray_at (size_t index)
 
const flexible_typearray_at (size_t index) const
 
flexible_typedict_at (const flexible_type &index)
 
const flexible_typedict_at (const flexible_type &index) const
 
flexible_typeoperator() (size_t index)
 
const flexible_typeoperator() (size_t index) const
 
flexible_typeoperator() (const flexible_type &index)
 
const flexible_typeoperator() (const flexible_type &index) const
 
size_t size () const
 
void resize (size_t s)
 
void clear ()
 
void erase (const flexible_type &index)
 
void push_back (flex_float i)
 
void push_back (const flexible_type &i)
 
void save (oarchive &oarc) const
 
void load (iarchive &iarc)
 
template<typename Visitor >
FLEX_ALWAYS_INLINE_FLATTEN auto apply_visitor (Visitor visitor) const -> decltype(visitor(prototype_flex_int))
 
template<typename Visitor >
FLEX_ALWAYS_INLINE_FLATTEN auto apply_visitor (Visitor visitor, const flexible_type &other) const -> decltype(visitor(prototype_flex_int, flex_int()))
 overload
 
template<typename T >
std::enable_if<!std::is_integral< T >::value &&!std::is_floating_point< T >::value, T >::type to () const
 
template<typename T >
std::enable_if< std::is_integral< T >::value, T >::type to () const
 
template<typename T >
std::enable_if< std::is_floating_point< T >::value, T >::type to () const
 

Detailed Description

The flexible_type is an automatic, self-managing union between the following types.

It is nearly every operator overloaded which allows it to behave very similarly to python data types.

The internal representation of the flexible_type is simply:

  • 8 bytes of (flex_int, flex_double, flex_string* and flex_vec*)
  • 1 byte tag corresponding to a member of the enumeration flex_type_enum
f += f2; // f is now 3
f += 1; // f is now 4
if (f == 4) std::cout << "!";
f = float(f); // convert f to float
f += 2.5; // f is now 6.5
// convert to string
f = std::string(f); f is now "5"
f += "hello"; // f is now "5hello"
// vector test
f = {1.1, 2.2}; // f is now a vector if {1.1, 2.2}
f.push_back(3.3); // f is now a vector if {1.1, 2.2, 3.3}
f.clear(); // f is now an empty vector
for (flexible_type i = 0;i < 10; ++i) {
f.push_back(i);
}
// f is now a vector from 1.0 to 10.0
f = std::string("hello"); // f is now a string again
f.mutable_get<flex_string>() = "boo"; // this gets a reference to the underlying storage
f.mutable_get<flex_int>() = 5; // this will implode at runtime

Type Information and Contents

The type information for the contents of the flexible type can be obtained in three ways.

  • flexible_type::get_type() Returns a member of the enumeration flex_type_enum
  • flexible_type::which() Returns a number corresponding to size_t(get_type()) Provided for compatibility with boost::variant
  • flexible_type::type() Returns a std::type_index object corresponding to the typeid of the stored object. Provided for compatibility with boost::variant

Knowing the type of the contents, the flexible_type::get() function can be used to extract a reference to the content.

f.mutable_get<flex_int>() = 10;
std::cout << f.get<flex_int>();

If the incorrect type is provided, the flexible_type::get() function will throw a runtime exception.

A large number of casting operators are also provided and these work as expected.

(int)f // casts doubles and integers to a integer. strings and vectors will fail.
(float)f // casts doubles and integers to a double . strings and vectors will fail.
(string)f // returns a printable string representation of all types.

However, there are certain ambiguous cases whch do cause issues when using the explicit cast so, the flexible_type::to() function is generally preferred:

f.to<int>()
f.to<float>()
f.to<string>()

Undefined

A special undefined type is provided which is useful for identifying missing values (or the None value/type in Python). Such a value can be created using:

flexible_type f = flex_undefined();
// or

Operators

Practically every operator is overloaded, and the behaviors are relatively intuitive. See the documentation for each operator to determine legality. There are also special operator overloads to simplify access to the vector. For instance, flexible_type::operator[], flexible_type::clear() and flexible_type::push_back(). In all cases, a runtime exception is thrown if an invalid type combination is encountered.

The basic rule of the flexible_type is that the internal type is always preserved. Only an assignment can change the internal type of the object. Also, for consistency, operations between two flexible types always return a type corresponding to the flexible_type on the left of the operation. i.e.

flexible_type f_int(5);
flexible_type f_float(2.1);
flexible_type f_res = f_int * f_float;
// the type of f_res is an integer
f_res = f_float * f_int;
// the type of f_res is a float

This is true also for operations where the 2nd argument is an arbitrary type.

flexible_type f_float(2.1);
flexible_type f_res = f_float + 2;
// the type of f_res is a float

The only exception to the rule is when the first argument is not a flexible type and the 2nd argument is a flexible type. In which case, the return type is the a flexible type corresponding to the type on the right.

flexible_type f_float(2.1);
flexible_type f_res = 2 + f_float;
// the type of f_res is a float

In summary: Where flexible_type_A is used to denote a flexible_type where the internal contents are of type A, and OP is an arbitrary operator,

  • flexible_type_A OP flexible_type_B ==> flexible_type_A
  • flexible_type_A OP T ==> flexible_type_A
  • T OP flexible_type_A ==> flexible_type_A

This does mean that the binary operators are not commutative when performed across different types. ex:

  • (integer * float) produces an integer
  • (float * integer) produces an float

Visitors

Of the most powerful feature of the flexible_type, is the visitor mechanism which is designed in a very similar manner to that of the boost::variant. See flexible_type::apply_visitor(Visitor) or flexible_type::apply_mutating_visitor(Visitor) for details.

Capability Checking

Sometimes it can be useful to be able to query (at runtime, or at compile time) whether certain flexible_type operations will succeed or not. A number of useful functions are provided.

Runtime Capability Queries:

Compile-time Capability Queries:

Performance

Performance of the flexible_type is generally extremely good. With modern compilers (sometimes with inlining limit bumped up) can sometimes produce code which is equivalent to, or runs as fast as the version using native types especially if certain type constraints are set-up before hand. For instance:

if (x.get_type() == flex_type_enum::INTEGER) {
... do a whole bunch of stuff on x ...
}

Integers and Floating point values are stored in-place inside the flexible_type. All other types are somewhat more complex (strings, vectors etc) and are optimized by copy on write. i.e.

flexible_type a = "hello world";

Both b and a will reference the same "hello world" until either one of them gets mutated. As such, all inplace operations (get(), apply_visitor(Visitor)) require const, but also have a mutating version (mutating_get(), apply_mutating_visitor(Visitor)).

Definition at line 249 of file flexible_type.hpp.

Constructor & Destructor Documentation

◆ flexible_type() [1/8]

FLEX_ALWAYS_INLINE turi::flexible_type::flexible_type ( )
inlinenoexcept

Default Constructor. By default constructs an integer of value 0.

Definition at line 1650 of file flexible_type.hpp.

◆ flexible_type() [2/8]

template<typename T >
turi::flexible_type::flexible_type ( std::initializer_list< T > &&  list)

Construct from initializer List. Makes a vector

◆ ~flexible_type()

FLEX_ALWAYS_INLINE_FLATTEN turi::flexible_type::~flexible_type ( )
inline

Destructor.

Definition at line 1661 of file flexible_type.hpp.

◆ flexible_type() [3/8]

FLEX_ALWAYS_INLINE_FLATTEN turi::flexible_type::flexible_type ( const flexible_type other)
inlinenoexcept

Copy constructor. Assigns this to a copy of other.

Definition at line 1669 of file flexible_type.hpp.

◆ flexible_type() [4/8]

FLEX_ALWAYS_INLINE_FLATTEN turi::flexible_type::flexible_type ( flexible_type other)
inlinenoexcept

Copy constructor. Assigns this to a copy of other.

Definition at line 1674 of file flexible_type.hpp.

◆ flexible_type() [5/8]

template<typename T >
turi::flexible_type::flexible_type ( const T &  other,
typename std::enable_if< has_direct_conversion_to_flexible_type< T >::value >::type = nullptr 
)

Copy constructor. Assigns this from arbitrary type. See flexible_type::operator=

◆ flexible_type() [6/8]

FLEX_ALWAYS_INLINE_FLATTEN turi::flexible_type::flexible_type ( flexible_type &&  other)
inlinenoexcept

Move constructor. Just assigns myself to the other, destroying the other.

Definition at line 1685 of file flexible_type.hpp.

◆ flexible_type() [7/8]

FLEX_ALWAYS_INLINE_FLATTEN turi::flexible_type::flexible_type ( const flexible_type &&  other)
inlinenoexcept

Move constructor. (Const overload. Required since the T&& universal reference has a tendency to capture everything)

Definition at line 1691 of file flexible_type.hpp.

◆ flexible_type() [8/8]

template<typename T >
turi::flexible_type::flexible_type ( T &&  other,
typename std::enable_if< has_direct_conversion_to_flexible_type< typename std::remove_reference< T >::type >::value >::type = nullptr 
)

Move constructor. Assigns this from arbitrary type

Member Function Documentation

◆ apply_mutating_visitor() [1/2]

template<typename Visitor >
auto turi::flexible_type::apply_mutating_visitor ( Visitor  visitor) -> decltype(visitor(prototype_flex_int))

Executes an apply visitor on the flexible type. The apply visitor object must have a function void operator()(T& t) for every type T the flexible type can contain. The operator() function can be itself templated for convenience. For instance, the following visitor will add the value "1" to the flexible_type if the flexible_type contains an integer, and will ignore otherwise.

struct add_one_to_integer {
// do nothing
template <typename T>
void operator()(T& t) { }
void operator()(flex_int& t) { t += 1; }
};

The visitor can return values but all versions of the operator() function must return exactly the same type. For instance:

struct add_one_and_return {
// do nothing
template <typename T>
int operator()(T& t) { return 0; }
int operator()(flex_int& t) { t += 1; return t; }
};

In which case, apply_mutating_visitor will return a value:

int ret = flex.apply_mutating_visitor(add_one_and_return());

This function assumes that the function will mutate the value. If the function does not mutate the value, the alternative apply_visitor(Visitor) should be used.

◆ apply_mutating_visitor() [2/2]

template<typename Visitor >
auto turi::flexible_type::apply_mutating_visitor ( Visitor  visitor,
const flexible_type other 
) -> decltype(visitor(prototype_flex_int, flex_int()))

Executes a binary visitor on the flexible type. The binary apply visitor object must have a function void operator()(T& t, const U& u) for every pair of types T and U the flexible type can contain. The operator() function can be itself templated for convenience. For instance, the following visitor will do a += if both types are integer.

struct add_one_to_integer {
// do nothing
template <typename T, typename U>
void operator()(T& t, const U& u) const { }
void operator()(flex_int& t, const flex_int& u) const { t += u; }
};

Just like the unary apply_mutating_visitor. the visitor can return a value, but all versions of operator() must return an identical type.

This function assumes that the function will mutate the value. If the function does not mutate the value, the alternative apply_visitor(Visitor, const flexible_type&) should be used.

◆ apply_visitor() [1/3]

template<typename Visitor >
auto turi::flexible_type::apply_visitor ( Visitor  visitor) const -> decltype(visitor(prototype_flex_int))

Executes a non-mutating apply visitor on the flexible type. The apply visitor object must have a function void operator()(const T& t) for every type T the flexible type can contain. The operator() function can be itself templated for convenience. For instance, the following visitor will return one plus the value of the flexible_type if it contains an integer, or returns 0 otherwise.

struct non_mutating_add_one {
// do nothing
template <typename T>
int operator()(T& t) { return 0; }
int operator()(flex_int& t) { return t + 1; }
};
int ret = flex.apply_visitor(non_mutating_add_one());

This function requires that the function does not mutate the value. If the function does mutate the value, the alternative apply_mutating_visitor(Visitor) should be used.

◆ apply_visitor() [2/3]

template<typename Visitor >
auto turi::flexible_type::apply_visitor ( Visitor  visitor,
const flexible_type other 
) const -> decltype(visitor(prototype_flex_int, flex_int()))

Executes a binary visitor on the flexible type. The binary apply visitor object must have a function void operator()(const T& t, const U& u) for every pair of types T and U the flexible type can contain. The operator() function can be itself templated for convenience. For instance, the following visitor will return the sum of both values if only if both types are integral.

struct add_one_to_integer {
// do nothing
template <typename T, typename U>
int operator()(T& t, const U& u) const { return 0; }
int operator()(flex_int& t, const flex_int& u) const { return t + u; }
};

Just like the unary apply_visitor. the visitor can return a value, but all versions of operator() must return an identical type.

This function assumes that the function will not mutate the value. If the function does mutate the value, the alternative apply_mutating_visitor(Visitor, const flexible_type&) should be used.

◆ apply_visitor() [3/3]

template<typename Visitor >
FLEX_ALWAYS_INLINE_FLATTEN auto turi::flexible_type::apply_visitor ( Visitor  visitor) const -> decltype(visitor(prototype_flex_int))
inline

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Definition at line 1928 of file flexible_type.hpp.

◆ approx_equal()

FLEX_ALWAYS_INLINE_FLATTEN bool turi::flexible_type::approx_equal ( const flexible_type other) const
inline

Compares if two flexible types are equivalent in value. i.e. permitting comparisons between integer and floating point types.

Definition at line 2212 of file flexible_type.hpp.

◆ array_at() [1/2]

FLEX_ALWAYS_INLINE_FLATTEN flexible_type & turi::flexible_type::array_at ( size_t  index)
inline

List indexing operator.

  • When the contents of the flexible_type is a list. Returns a reference to the 'index' entry in the vector.
  • All other types will result in an assertion failure.

Definition at line 2323 of file flexible_type.hpp.

◆ array_at() [2/2]

FLEX_ALWAYS_INLINE_FLATTEN const flexible_type & turi::flexible_type::array_at ( size_t  index) const
inline

List indexing operator.

  • When the contents of the flexible_type is a list. Returns a reference to the 'index' entry in the vector.
  • All other types will result in an assertion failure.

Definition at line 2329 of file flexible_type.hpp.

◆ clear()

FLEX_ALWAYS_INLINE_FLATTEN void turi::flexible_type::clear ( )
inline

Array clear function.

  • When the contents of the flexible_type is a vector, clears the vector.
  • When the contents of the flexible_type is a recursive object, clears the recursive array
  • All other types will result in an assertion failure.

Definition at line 2435 of file flexible_type.hpp.

◆ contains_na()

bool turi::flexible_type::contains_na ( ) const

Returns true if the value, or any contained value in a dictionary or list type, is considered a "missing value" or NA.

◆ dict_at() [1/2]

FLEX_ALWAYS_INLINE_FLATTEN flexible_type & turi::flexible_type::dict_at ( const flexible_type index)
inline

dict indexing operator.

  • When the contents of the flexible_type is a dictionary, Returns a reference to the 'index' entry in the dict array.
  • All other types will result in an assertion failure.

Definition at line 2334 of file flexible_type.hpp.

◆ dict_at() [2/2]

FLEX_ALWAYS_INLINE_FLATTEN const flexible_type & turi::flexible_type::dict_at ( const flexible_type index) const
inline

dict indexing operator.

  • When the contents of the flexible_type is a dictionary, Returns a reference to the 'index' entry in the dict array.
  • All other types will result in an assertion failure.

Definition at line 2349 of file flexible_type.hpp.

◆ erase()

void turi::flexible_type::erase ( const flexible_type index)

Dict element erase function.

  • When the contents of the flexible_type is a dict, erases the element indexed by the index value.
  • All other types will result in an assertion failure.

◆ get()

template<typename T >
const T& turi::flexible_type::get ( ) const

Gets a const reference to the value stored inside the flexible_type. T must be one of the flexible_type types. All other types will result in a compile type assertion failure. If the stored type does not match T, it will result in a run-time assertion failure.

◆ get_date_time_as_timestamp_and_offset()

FLEX_ALWAYS_INLINE std::pair< flex_int, int32_t > turi::flexible_type::get_date_time_as_timestamp_and_offset ( ) const
inline

Where the current flexible_type contains a datetime type, returns the datetime as a pair of posix timestamp value and its timezone offset.

The timezone offset is integral in fifteen-minute increments. i.e. a offset of 8 means timezone +2

Definition at line 1452 of file flexible_type.hpp.

◆ get_date_time_microsecond()

FLEX_ALWAYS_INLINE int32_t turi::flexible_type::get_date_time_microsecond ( ) const
inline

Gets the date_time microsecond value

Definition at line 1459 of file flexible_type.hpp.

◆ get_type()

flex_type_enum FLEX_ALWAYS_INLINE turi::flexible_type::get_type ( ) const
inline

Returns the type of the underlying storage

Definition at line 1867 of file flexible_type.hpp.

◆ hash()

FLEX_ALWAYS_INLINE size_t turi::flexible_type::hash ( ) const
inline

Returns a 64 bit hash of the underlying value, switched on type.

Definition at line 1880 of file flexible_type.hpp.

◆ hash128()

FLEX_ALWAYS_INLINE uint128_t turi::flexible_type::hash128 ( ) const
inline

Returns a 128 bit hash of the underlying value, switched on type. This hash is appropriate for unique identification.

Definition at line 1884 of file flexible_type.hpp.

◆ identical()

FLEX_ALWAYS_INLINE_FLATTEN bool turi::flexible_type::identical ( const flexible_type other) const
inline

Like operator== but requires also types to be equivalent.

Definition at line 2216 of file flexible_type.hpp.

◆ is_na()

bool turi::flexible_type::is_na ( ) const
inline

Returns true if the value is considered a "missing value" or NA.

◆ is_zero()

bool turi::flexible_type::is_zero ( ) const
inline

Returns true if the value is equal to this type's equivalent of zero.

◆ load()

FLEX_ALWAYS_INLINE void turi::flexible_type::load ( iarchive iarc)
inline

Deserializer. Loads the flexible_type from an archive object. Note that the type of the flexible_type may change.

Definition at line 2489 of file flexible_type.hpp.

◆ mutable_get()

template<typename T >
T& turi::flexible_type::mutable_get ( )

Gets a modifiable reference to the value stored inside the flexible_type. T must be one of the flexible_type types. All other types will result in a compile type assertion failure. If the stored type does not match T, it will result in a run-time assertion failure.

◆ operator flex_date_time()

FLEX_ALWAYS_INLINE_FLATTEN turi::flexible_type::operator flex_date_time ( ) const
inline

Implicit cast to flex_date_time

Definition at line 2121 of file flexible_type.hpp.

◆ operator flex_dict()

FLEX_ALWAYS_INLINE_FLATTEN turi::flexible_type::operator flex_dict ( ) const
inline

Implicit cast to vector<pair<flexible_type, flexible_type>>

Definition at line 2117 of file flexible_type.hpp.

◆ operator flex_image()

FLEX_ALWAYS_INLINE_FLATTEN turi::flexible_type::operator flex_image ( ) const
inline

Implicit cast to flex_image

Definition at line 2125 of file flexible_type.hpp.

◆ operator flex_list()

FLEX_ALWAYS_INLINE_FLATTEN turi::flexible_type::operator flex_list ( ) const
inline

Implicit cast to vector<flexible_type>

Definition at line 2113 of file flexible_type.hpp.

◆ operator flex_nd_vec()

FLEX_ALWAYS_INLINE_FLATTEN turi::flexible_type::operator flex_nd_vec ( ) const
inline

Implicit cast to ndarray<double>

Definition at line 2109 of file flexible_type.hpp.

◆ operator flex_string()

FLEX_ALWAYS_INLINE_FLATTEN turi::flexible_type::operator flex_string ( ) const
inline

Implicit cast to string

Definition at line 2101 of file flexible_type.hpp.

◆ operator flex_vec()

FLEX_ALWAYS_INLINE_FLATTEN turi::flexible_type::operator flex_vec ( ) const
inline

Implicit cast to vector<double>

Definition at line 2105 of file flexible_type.hpp.

◆ operator!=() [1/2]

FLEX_ALWAYS_INLINE_FLATTEN bool turi::flexible_type::operator!= ( const flexible_type other) const
inline

Compares if two flexible types are not equivalent in value. i.e. permitting comparisons between integer and floating point types. Same as flexible_type::approx_equal

Definition at line 2208 of file flexible_type.hpp.

◆ operator!=() [2/2]

template<typename T >
bool turi::flexible_type::operator!= ( const T &  other) const

Equality comparison operator with arbitrary type. Equivalent to (*this) != (flexible_type)(other);

◆ operator%() [1/2]

FLEX_ALWAYS_INLINE_FLATTEN flexible_type turi::flexible_type::operator% ( const flexible_type other) const
inline

Modulus operator. Equivalent to

a = (*this);
a %= otrer;
return a;

Note that unlike regular C++ typing rules, the resultant type is always the type of the left hand side. i.e. int + float = int, and float + int = float.

Definition at line 2195 of file flexible_type.hpp.

◆ operator%() [2/2]

template<typename T >
flexible_type turi::flexible_type::operator% ( const T &  other) const

Modulos operator with arbitrary type. Equivalent to (*this) % (flexible_type)(other);

◆ operator%=()

FLEX_ALWAYS_INLINE_FLATTEN flexible_type & turi::flexible_type::operator%= ( const flexible_type other)
inline

mod-equal operator.

  • If both are numeric types (int / float), the %= will behave as expected.
  • If the left hand side is a vector, and right hand side is an int/float, the right hand side value will be divided from each value in the vector.
  • All other conditions will result in an assertion failure.

Definition at line 2156 of file flexible_type.hpp.

◆ operator()() [1/4]

FLEX_ALWAYS_INLINE_FLATTEN flexible_type & turi::flexible_type::operator() ( size_t  index)
inline

List indexing operator.

  • When the contents of the flexible_type is a list or dict Returns a reference to the 'index' entry in the vector.
  • All other types will result in an assertion failure.

Definition at line 2361 of file flexible_type.hpp.

◆ operator()() [2/4]

FLEX_ALWAYS_INLINE_FLATTEN const flexible_type & turi::flexible_type::operator() ( size_t  index) const
inline

List indexing operator.

  • When the contents of the flexible_type is a list or dict, Returns a reference to the 'index' entry in the vector.
  • All other types will result in an assertion failure.

Definition at line 2373 of file flexible_type.hpp.

◆ operator()() [3/4]

FLEX_ALWAYS_INLINE_FLATTEN flexible_type & turi::flexible_type::operator() ( const flexible_type index)
inline

DIct indexing operator.

  • When the contents of the flexible_type is a dict, Returns a reference to the 'index' entry in the dict array.
  • All other types will result in an assertion failure.

Definition at line 2383 of file flexible_type.hpp.

◆ operator()() [4/4]

FLEX_ALWAYS_INLINE_FLATTEN const flexible_type & turi::flexible_type::operator() ( const flexible_type index) const
inline

Dict indexing operator.

  • When the contents of the flexible_type is a dict, Returns a reference to the 'index' entry in the dict array.
  • All other types will result in an assertion failure.

Definition at line 2395 of file flexible_type.hpp.

◆ operator*() [1/2]

FLEX_ALWAYS_INLINE_FLATTEN flexible_type turi::flexible_type::operator* ( const flexible_type other) const
inline

Multiplication operator. Equivalent to

a = (*this);
a *= other;
return a;

Note that unlike regular C++ typing rules, the resultant type is always the type of the left hand side. i.e. int + float = int, and float + int = float.

Definition at line 2180 of file flexible_type.hpp.

◆ operator*() [2/2]

template<typename T >
flexible_type turi::flexible_type::operator* ( const T &  other) const

Multiplication operator with arbitrary type. Equivalent to (*this) * (flexible_type)(other);

◆ operator*=()

FLEX_ALWAYS_INLINE_FLATTEN flexible_type & turi::flexible_type::operator*= ( const flexible_type other)
inline

times-equal operator.

  • If both are numeric types (int / float), the *= will behave as expected.
  • If the left hand side is a vector, and right hand side is an int/float, the right hand side value will be multiplied to each value in the vector.
  • All other conditions will result in an assertion failure.

Definition at line 2161 of file flexible_type.hpp.

◆ operator+() [1/2]

FLEX_ALWAYS_INLINE_FLATTEN flexible_type turi::flexible_type::operator+ ( const flexible_type other) const
inline

Plus operator.

a = (*this);
a += other;
return a;

Note that unlike regular C++ typing rules, the resultant type is always the type of the left hand side. i.e. int + float = int, and float + int = float.

Definition at line 2167 of file flexible_type.hpp.

◆ operator+() [2/2]

template<typename T >
flexible_type turi::flexible_type::operator+ ( const T &  other) const

Addition operator with arbitrary type. Equivalent to (*this) + (flexible_type)(other);

◆ operator+=()

FLEX_ALWAYS_INLINE_FLATTEN flexible_type & turi::flexible_type::operator+= ( const flexible_type other)
inline

plus-equal operator.

  • If both are numeric types (int / flex_float), the += will behave as expected.
  • If both are strings, the += will append.
  • If both are vectors, the += will perform a vector addition.
  • If the left hand side is a vector, and right hand side is an int/float, the right hand side value will be added to each value in the vector.
  • All other conditions will result in an assertion failure.

Definition at line 2136 of file flexible_type.hpp.

◆ operator-() [1/3]

FLEX_ALWAYS_INLINE_FLATTEN flexible_type turi::flexible_type::operator- ( ) const
inline

negation operator.

  • negation operator.
  • If the value is a numeric, the negation will return a negated value of the same type.
  • If the value is a vector, the negation will return a vector with every element negated.
  • All other conditions will result in an assertion failure.

Definition at line 2129 of file flexible_type.hpp.

◆ operator-() [2/3]

FLEX_ALWAYS_INLINE_FLATTEN flexible_type turi::flexible_type::operator- ( const flexible_type other) const
inline

Subtract operator. Equivalent to

a = (*this);
a += other;
return a;

Note that unlike regular C++ typing rules, the resultant type is always the type of the left hand side. i.e. int + float = int, and float + int = float.

Definition at line 2173 of file flexible_type.hpp.

◆ operator-() [3/3]

template<typename T >
flexible_type turi::flexible_type::operator- ( const T &  other) const

Subtract operator with arbitrary type. Equivalent to (*this) - (flexible_type)(other);

◆ operator-=()

FLEX_ALWAYS_INLINE_FLATTEN flexible_type & turi::flexible_type::operator-= ( const flexible_type other)
inline

subtract-equal operator.

  • If both are numeric types (int / float), the -= will behave as expected.
  • If both are vectors, the -= will perform a vector subtraction.
  • If the left hand side is a vector, and right hand side is an int/float, the right hand side value will be subtracted from each value in the vector.
  • All other conditions will result in an assertion failure.

Definition at line 2142 of file flexible_type.hpp.

◆ operator/() [1/2]

FLEX_ALWAYS_INLINE_FLATTEN flexible_type turi::flexible_type::operator/ ( const flexible_type other) const
inline

Division operator. Equivalent to

a = (*this);
a /= other;
return a;

Note that unlike regular C++ typing rules, the resultant type is always the type of the left hand side. i.e. int + float = int, and float + int = float.

Definition at line 2188 of file flexible_type.hpp.

◆ operator/() [2/2]

template<typename T >
flexible_type turi::flexible_type::operator/ ( const T &  other) const

Division operator with arbitrary type. Equivalent to (*this) / (flexible_type)(other);

◆ operator/=()

FLEX_ALWAYS_INLINE_FLATTEN flexible_type & turi::flexible_type::operator/= ( const flexible_type other)
inline

divide-equal operator.

  • If both are numeric types (int / float), the /= will behave as expected.
  • If the left hand side is a vector, and right hand side is an int/float, the right hand side value will be divided from each value in the vector.
  • All other conditions will result in an assertion failure.

Definition at line 2149 of file flexible_type.hpp.

◆ operator<() [1/2]

FLEX_ALWAYS_INLINE_FLATTEN bool turi::flexible_type::operator< ( const flexible_type other) const
inline

Less than operator.

  • If both this and other are int / floats. this behaves as expected
  • All other cases will result in an assertion failure

Definition at line 2220 of file flexible_type.hpp.

◆ operator<() [2/2]

template<typename T >
bool turi::flexible_type::operator< ( const T &  other) const

Less than comparison operator with arbitrary type. Equivalent to (*this) < (flexible_type)(other);

◆ operator<=() [1/2]

FLEX_ALWAYS_INLINE_FLATTEN bool turi::flexible_type::operator<= ( const flexible_type other) const
inline

less than or equal than operator.

  • If both this and other are int / floats. this behaves as expected
  • All other cases will result in an assertion failure

Definition at line 2228 of file flexible_type.hpp.

◆ operator<=() [2/2]

template<typename T >
bool turi::flexible_type::operator<= ( const T &  other) const

Less than or equal comparison operator with arbitrary type. Equivalent to (*this) <= (flexible_type)(other);

◆ operator=() [1/7]

FLEX_ALWAYS_INLINE_FLATTEN flexible_type & turi::flexible_type::operator= ( const flexible_type other)
inlinenoexcept

Assignment operator. Copies the other to myself. See flexible_type::operator=

Definition at line 1710 of file flexible_type.hpp.

◆ operator=() [2/7]

FLEX_ALWAYS_INLINE_FLATTEN flexible_type & turi::flexible_type::operator= ( flexible_type other)
inlinenoexcept

Assignment operator. Copies the other to myself. See flexible_type::operator=

Definition at line 1719 of file flexible_type.hpp.

◆ operator=() [3/7]

FLEX_ALWAYS_INLINE_FLATTEN flexible_type & turi::flexible_type::operator= ( flexible_type &&  other)
inlinenoexcept

Move assignment. Assigns myself from the other, destroying the other.

Definition at line 1738 of file flexible_type.hpp.

◆ operator=() [4/7]

FLEX_ALWAYS_INLINE_FLATTEN flexible_type & turi::flexible_type::operator= ( const flexible_type &&  other)
inlinenoexcept

Move assignment. (Const overload. Required since the T&& universal reference has a tendency to capture everything).

Definition at line 1728 of file flexible_type.hpp.

◆ operator=() [5/7]

template<typename T >
std::enable_if< has_direct_conversion_to_flexible_type<T>::value, flexible_type&>::type turi::flexible_type::operator= ( const T &  other)

Assignment from arbitrary type. Figures out what can be casted from provided argument and stores that. Specifically, it tests the following operations in this order.

  • If T is an integral type, create a flexible_type of an integer
  • If T is a floating point type, create a flexible_type of a float
  • If T can be converted to a string, create a flexible_type of a string
  • If T can be converted to a flex_vec. create a flexible_type of a flex_vec.

◆ operator=() [6/7]

FLEX_ALWAYS_INLINE_FLATTEN flexible_type & turi::flexible_type::operator= ( flex_undefined  other)
inline

operator= for the undefined type See flexible_type::operator=

Definition at line 1761 of file flexible_type.hpp.

◆ operator=() [7/7]

template<typename T >
std::enable_if<has_direct_conversion_to_flexible_type< typename std::remove_reference<T>::type>::value, flexible_type&>::type turi::flexible_type::operator= ( T &&  other)

Move assignment from arbitrary type. Figures out what can be casted from provided argument and stores that. Specifically, it tests the following operations in this order.

  • If T is an integral type, create a flexible_type of an integer
  • If T is a floating point type, create a flexible_type of a float
  • If T can be converted to a string, create a flexible_type of a string
  • If T can be converted to a flex_vec. create a flexible_type of a flex_vec.

◆ operator==() [1/2]

FLEX_ALWAYS_INLINE_FLATTEN bool turi::flexible_type::operator== ( const flexible_type other) const
inline

Compares if two flexible types are equivalent in value. i.e. permitting comparisons between integer and floating point types. Same as flexible_type::approx_equal

Definition at line 2203 of file flexible_type.hpp.

◆ operator==() [2/2]

template<typename T >
bool turi::flexible_type::operator== ( const T &  other) const

Equality comparison operator with arbitrary type. Equivalent to (*this) == (flexible_type)(other);

◆ operator>() [1/2]

FLEX_ALWAYS_INLINE_FLATTEN bool turi::flexible_type::operator> ( const flexible_type other) const
inline

greater than operator.

  • If both this and other are int / floats. this behaves as expected
  • All other cases will result in an assertion failure

Definition at line 2224 of file flexible_type.hpp.

◆ operator>() [2/2]

template<typename T >
bool turi::flexible_type::operator> ( const T &  other) const

Greater than comparison operator with arbitrary type. Equivalent to (*this) > (flexible_type)(other);

◆ operator>=() [1/2]

FLEX_ALWAYS_INLINE_FLATTEN bool turi::flexible_type::operator>= ( const flexible_type other) const
inline

greater than or equal than operator.

  • If both this and other are int / floats. this behaves as expected
  • All other cases will result in an assertion failure

Definition at line 2232 of file flexible_type.hpp.

◆ operator>=() [2/2]

template<typename T >
bool turi::flexible_type::operator>= ( const T &  other) const

Greater than or equal comparison operator with arbitrary type. Equivalent to (*this) >= (flexible_type)(other);

◆ operator[]() [1/2]

FLEX_ALWAYS_INLINE_FLATTEN flex_float & turi::flexible_type::operator[] ( size_t  index)
inline

Array indexing operator.

  • When the contents of the flexible_type is a vector, Returns a reference to the 'index' entry in the vector.
  • When the contents is a float, returns a reference to the float only if the index is 0. (i.e. letting the scalar float act like a vector of size 1. All other indexes will fail with an assertion failure.
  • All other types will result in an assertion failure.

Definition at line 2293 of file flexible_type.hpp.

◆ operator[]() [2/2]

FLEX_ALWAYS_INLINE_FLATTEN const flex_float & turi::flexible_type::operator[] ( size_t  index) const
inline

Array indexing operator.

  • When the contents of the flexible_type is a vector, Returns a reference to the 'index' entry in the vector.
  • When the contents is a float, returns a reference to the float only if the index is 0. (i.e. letting the scalar float act like a vector of size 1. All other indexes will fail with an assertion failure.
  • All other types will result in an assertion failure.

Definition at line 2308 of file flexible_type.hpp.

◆ push_back() [1/2]

FLEX_ALWAYS_INLINE_FLATTEN void turi::flexible_type::push_back ( flex_float  i)
inline

Array insertion function.

  • When the contents of the flexible_type is a vector, inserts the element to the end of the vector.
  • When the contents of the flexible_type is a recursive array, inserts a float to the end of the vector.
  • All other types will result in an assertion failure.

Definition at line 2448 of file flexible_type.hpp.

◆ push_back() [2/2]

FLEX_ALWAYS_INLINE_FLATTEN void turi::flexible_type::push_back ( const flexible_type i)
inline

Array / List insertion function.

  • When the contents of the flexible_type is a vector, and the element is a floating point number, inserts the element to the end of the vector.
  • When the contents of the flexible_type is a list, inserts a value to the end of the vector.
  • All other types will result in an assertion failure.

Definition at line 2463 of file flexible_type.hpp.

◆ reinterpret_get()

template<typename T >
const T& turi::flexible_type::reinterpret_get ( ) const

Gets a type unchecked modifiable reference to the value stored inside the flexible_type.

This is generally unsafe to use unless you really know what you are doing. Use get() instead.

Note that this is only defined for flex_int and flex_float type. It really does not make sense to use this anywhere else.

◆ reinterpret_mutable_get()

template<typename T >
T& turi::flexible_type::reinterpret_mutable_get ( )

Gets a modifiable type unchecked modifiable reference to the value stored inside the flexible_type.

This is generally unsafe to use unless you really know what you are doing. Use get() instead.

Note that this is only defined for flex_int and flex_float type. It really does not make sense to use this anywhere else.

◆ reset() [1/2]

FLEX_ALWAYS_INLINE_FLATTEN void turi::flexible_type::reset ( flex_type_enum  target_type)
inline

Deletes the contents of this class, resetting to a different type.

Note: Also ensures that that the reference count becomes 1.

Definition at line 1782 of file flexible_type.hpp.

◆ reset() [2/2]

FLEX_ALWAYS_INLINE_FLATTEN void turi::flexible_type::reset ( )
inline

Deletes the contents of this class, resetting to an integer

Definition at line 1825 of file flexible_type.hpp.

◆ resize()

FLEX_ALWAYS_INLINE_FLATTEN void turi::flexible_type::resize ( size_t  s)
inline

Array resize function

  • When the contents of the flexible_type is a vector or a recursive array resizes the array
  • All other types will result in an assertion failure.

Definition at line 2421 of file flexible_type.hpp.

◆ save()

FLEX_ALWAYS_INLINE void turi::flexible_type::save ( oarchive oarc) const
inline

Serializer. Saves the flexible_type in an archive object.

Definition at line 2479 of file flexible_type.hpp.

◆ set_date_time_from_timestamp_and_offset()

FLEX_ALWAYS_INLINE_FLATTEN flexible_type & turi::flexible_type::set_date_time_from_timestamp_and_offset ( const std::pair< flex_int, int32_t > &  datetime,
const int32_t  microsecond = 0 
)
inline

Converts the current flexible type to a datetime type containing posix_timestamp value and timezone offset. The timezone offset is integral in fifteen-minute increments. i.e. a offset of 8 means timezone +2

Definition at line 1464 of file flexible_type.hpp.

◆ size()

FLEX_ALWAYS_INLINE_FLATTEN size_t turi::flexible_type::size ( ) const
inline

Array length function.

  • When the contents of the flexible_type is a vector or a recursive array Returns the length of the vector.
  • When the contents is a float, returns 1 (i.e. letting the scalar float act like a vector of size 1.)
  • All other types will result in an assertion failure.

Definition at line 2406 of file flexible_type.hpp.

◆ soft_assign()

FLEX_ALWAYS_INLINE_FLATTEN flexible_type & turi::flexible_type::soft_assign ( const flexible_type other)
inline

Assign from another while preserving the type of the current flexible_type.

  • If left side is numeric and right side is numeric, the operation works as expected.
  • If left side is a string, the right side is converted to a string representation
  • if left side is a vector and right side is a vector, the vector is copied.
  • All other cases will result in an assertion failure.

Definition at line 1703 of file flexible_type.hpp.

◆ swap()

FLEX_ALWAYS_INLINE_FLATTEN void turi::flexible_type::swap ( flexible_type b)
inline

Swaps contents with another flexible_type

Definition at line 1833 of file flexible_type.hpp.

◆ to() [1/3]

template<typename T >
std::enable_if<!std::is_integral<T>::value && !std::is_floating_point<T>::value, T>::type turi::flexible_type::to ( ) const

Converts the flexible_type to a particular type. Behaves like the implicit cast operators, but explicit. In particular, this gets around the thorny issue that there is no way to cast to an flex_vec, flex_list or flex_dict even though the implicit cast operators exist. This is due to std::vector<T> having two constructors:

// regular copy constructor
vector<T>::vector(const std::vector<T>&) ...
// constructs a vector of a particular size
vector<T>::vector(size_t N, T val = T()) ...

Resulting in two possible implicit cast routes when doing:

...
flex_vec v = f; // fails
flex_vec v = (flex_vec)f; // fails

This function provides an explicit cast allowing the following to be written:

flex_vec v = f.to<flex_vec>();

Of course, the alternative of is always available.

flex_vec v = f.operator flex_vec();

And indeed, the implementation of to() simply redirects the calls.

◆ to() [2/3]

template<typename T >
std::enable_if<std::is_integral<T>::value, T>::type turi::flexible_type::to ( ) const

Converts the flexible_type to a particular type. Behaves like the implicit cast operators, but explicit. In particular, this gets around the thorny issue that there is no way to cast to an flex_vec, flex_list or flex_dict even though the implicit cast operators exist. This is due to std::vector<T> having two constructors:

// regular copy constructor
vector<T>::vector(const std::vector<T>&) ...
// constructs a vector of a particular size
vector<T>::vector(size_t N, T val = T()) ...

Resulting in two possible implicit cast routes when doing:

...
flex_vec v = f; // fails
flex_vec v = (flex_vec)f; // fails

This function provides an explicit cast allowing the following to be written:

flex_vec v = f.to<flex_vec>();

Of course, the alternative of is always available.

flex_vec v = f.operator flex_vec();

And indeed, the implementation of to() simply redirects the calls.

◆ to() [3/3]

template<typename T >
std::enable_if<std::is_floating_point<T>::value, T>::type turi::flexible_type::to ( ) const

Converts the flexible_type to a particular type. Behaves like the implicit cast operators, but explicit. In particular, this gets around the thorny issue that there is no way to cast to an flex_vec, flex_list or flex_dict even though the implicit cast operators exist. This is due to std::vector<T> having two constructors:

// regular copy constructor
vector<T>::vector(const std::vector<T>&) ...
// constructs a vector of a particular size
vector<T>::vector(size_t N, T val = T()) ...

Resulting in two possible implicit cast routes when doing:

...
flex_vec v = f; // fails
flex_vec v = (flex_vec)f; // fails

This function provides an explicit cast allowing the following to be written:

flex_vec v = f.to<flex_vec>();

Of course, the alternative of is always available.

flex_vec v = f.operator flex_vec();

And indeed, the implementation of to() simply redirects the calls.

◆ type()

FLEX_ALWAYS_INLINE std::type_index turi::flexible_type::type ( ) const
inline

Returns the type index of the underlying storage. For compatibility with variant.

Definition at line 1872 of file flexible_type.hpp.

◆ which()

FLEX_ALWAYS_INLINE size_t turi::flexible_type::which ( ) const
inline

Returns an integer ID identifying the type of the underlying storage. Equivalent to (size_t)(get_type()). For compatibility with variant.

Definition at line 1876 of file flexible_type.hpp.


The documentation for this class was generated from the following file: