ArrayFactory Class Reference

#include <array.h>

Detailed Description

ArrayFactory provides static methods to create arrays of various implementations of the ArrayInterface in a generic way.

Static Public Member Functions

static MAXON_METHOD Result< ArrayInterface< Generic > * > NewBaseArray (const DataType &elementType, const Generic *src, Bool move)
 
static Result< ArrayInterface< Generic > * > NewBaseArray (const DataType &type, Int size=0, COLLECTION_RESIZE_FLAGS flags=COLLECTION_RESIZE_FLAGS::DEFAULT)
 
static MAXON_METHOD Result< ArrayInterface< Generic > * > NewBaseArrayFromContainerType (const ContainerDataType<> &containerType, const Generic *src, Bool move)
 
template<typename T >
static Result< Array< T > > NewBaseArray ()
 
template<typename T >
static Result< Array< T > > NewBaseArray (const BaseArray< T > &src)
 
template<typename T >
static Result< Array< T > > NewBaseArray (BaseArray< T > &&src)
 
static MAXON_METHOD Result< ArrayInterface< Generic > * > NewBlockArray (const DataType &elementType, const Generic *src, Bool move)
 
template<typename T >
static Result< Array< T > > NewBlockArray ()
 
static MAXON_METHOD Result< Array< Generic > > NewPagedArray (const DataType &elementType, const Generic *defaultValue=nullptr, Bool useRefCountForDefault=false)
 
static MAXON_METHOD Result< Array< Generic > > NewPagedArrayFromContainerType (const ContainerDataType<> &containerType, const Generic *defaultValue=nullptr, Bool useRefCountForDefault=false)
 
template<typename T >
static Result< Array< T > > NewPagedArray ()
 
static MAXON_METHOD Result< Array< Generic > > Slice (const Array< Generic > &base, Int start, Int end, Bool cycle, const Generic *defaultValue=nullptr, Bool useRefCountForDefault=false)
 
template<typename T >
static Result< Array< T > > Slice (const Array< T > &base, Int start, Int end)
 
template<typename T >
static Result< Array< T > > Slice (const Array< T > &base, Int start, Int end, Bool cycle, const T *defaultValue=nullptr, Bool useRefCountForDefault=false)
 
static MAXON_METHOD Result< Array< Generic > > NewSingleValueArray (const ConstDataPtr &value, Int count, const ContainerDataType<> &containerType=GetPtrSizedZeroRef< ContainerDataType<>>())
 
template<typename T >
static Result< Array< T > > NewSingleValueArray (const T &value, Int count)
 
static MAXON_METHOD Result< Array< Generic > > ExtractMember (const Array< Generic > &base, Int offset, const ContainerDataType<> &containerType)
 
template<typename DST , typename SRC >
static Result< Array< DST > > ExtractMember (const Array< SRC > &base, Int offset)
 
static MAXON_METHOD Result< Array< Generic > > Reinterpret (const Array< Generic > &base, const ContainerDataType<> &containerType)
 
template<typename DST , typename SRC >
static Result< Array< DST > > Reinterpret (const Array< SRC > &base)
 
static MAXON_METHOD Result< Array< Generic > > PrivateNewPagedArrayFromBase (const Array< Generic > &base, const Generic *defaultValue=nullptr, Bool useRefCountForDefault=false)
 
template<typename T >
static Result< Array< T > > PrivateNewPagedArrayFromBase (const Array< T > &base)
 
static MAXON_METHOD Result< Array< Generic > > ConvertToSingleBlock (const Array< Generic > &source)
 
template<typename T >
static Result< Array< T > > ConvertToSingleBlock (const Array< T > &source)
 

Private Member Functions

 MAXON_INTERFACE_NONVIRTUAL (ArrayFactory, MAXON_REFERENCE_NONE, "net.maxon.interface.arrayfactory")
 

Member Function Documentation

◆ MAXON_INTERFACE_NONVIRTUAL()

MAXON_INTERFACE_NONVIRTUAL ( ArrayFactory  ,
MAXON_REFERENCE_NONE  ,
"net.maxon.interface.arrayfactory"   
)
private

◆ NewBaseArray() [1/5]

static MAXON_METHOD Result<ArrayInterface<Generic>*> NewBaseArray ( const DataType elementType,
const Generic *  src,
Bool  move 
)
static

Creates a new array which uses an internal BaseArray implementation. All elements will be in a single contiguous memory block.

The implementation has to obtain the container type from the given element type. In performance-critical code you should do that yourself outside of the performance-critical part and use the method NewBaseArrayFromContainerType.

Parameters
[in]elementTypeThe element type of the array.
[in]srcA pointer to a BaseArray<T> where T matches the given element type. This will be used to initialize the new array by copying or moving the elements. If src is nullptr, the new array will be empty.
[in]moveIf true, src will be moved into the new array. Note that this has to make a const_cast of the src parameter.
Returns
Newly created array.

◆ NewBaseArray() [2/5]

static Result<ArrayInterface<Generic>*> NewBaseArray ( const DataType type,
Int  size = 0,
COLLECTION_RESIZE_FLAGS  flags = COLLECTION_RESIZE_FLAGS::DEFAULT 
)
static

Creates a new array of the given size which uses an internal BaseArray implementation. All elements will be in a single contiguous memory block and have default-initialized values.

The implementation has to obtain the container type from the given element type. In performance-critical code you should do that yourself outside of the performance-critical part and use the method NewBaseArrayFromContainerType.

Parameters
[in]elementTypeThe element type of the array.
[in]sizeThe initial size of the array.
[in]flagsFlags for the initial resize operation.
Returns
Newly created array.

◆ NewBaseArrayFromContainerType()

static MAXON_METHOD Result<ArrayInterface<Generic>*> NewBaseArrayFromContainerType ( const ContainerDataType<> &  containerType,
const Generic *  src,
Bool  move 
)
static

Creates a new array which uses an internal BaseArray implementation. All elements will be in a single contiguous memory block.

This method requires to pass the container type instead of the element type, but it's faster than NewBaseArray. To obtain the container type from an element type, you can use this code:

ContainerDataType<> t = ParametricTypes::ContainerInterface().Instantiate(elementType) iferr_return;
#define iferr_return
Definition: resultbase.h:1465
Parameters
[in]containerTypeThe container type of the array.
[in]srcA pointer to a BaseArray<T> where T matches the array's element type. This will be used to initialize the new array by copying or moving the elements. If src is nullptr, the new array will be empty.
[in]moveIf true, src will be moved into the new array. Note that this has to make a const_cast of the src parameter.
Returns
Newly created array.

◆ NewBaseArray() [3/5]

static Result<Array<T> > NewBaseArray ( )
static

Creates a new array which uses an internal BaseArray implementation. All elements will be in a single contiguous memory block.

Template Parameters
TElement type of the array to create.
Returns
Newly created array.

◆ NewBaseArray() [4/5]

static Result<Array<T> > NewBaseArray ( const BaseArray< T > &  src)
static

Creates a new array which uses an internal BaseArray implementation and is copy-initialized from src. All elements will be in a single contiguous memory block.

Parameters
[in]srcA BaseArray<T> to copy-initialize the new array.
Template Parameters
TElement type of the array to create.
Returns
Newly created array.

◆ NewBaseArray() [5/5]

static Result<Array<T> > NewBaseArray ( BaseArray< T > &&  src)
static

Creates a new array which uses an internal BaseArray implementation and is move-initialized from src. All elements will be in a single contiguous memory block.

Parameters
[in]srcA BaseArray<T> to move-initialize the new array.
Template Parameters
TElement type of the array to create.
Returns
Newly created array.

◆ NewBlockArray() [1/2]

static MAXON_METHOD Result<ArrayInterface<Generic>*> NewBlockArray ( const DataType elementType,
const Generic *  src,
Bool  move 
)
static

Creates a new array which uses an internal BlockArray implementation. Not all element types are supported. You can use NewPagedArray for a similar implementation which has the possibility to share copy-on-write blocks among several arrays.

Parameters
[in]elementTypeThe element type of the array. Not all element types are supported.
[in]srcA pointer to a BlockArray<T> where T matches the given element type. This will be used to initialize the new array by copying or moving the elements. If src is nullptr, the new array will be empty.
[in]moveIf true, src will be moved into the new array. Note that this has to make a const_cast of the src parameter.
Returns
Newly created array.

◆ NewBlockArray() [2/2]

static Result<Array<T> > NewBlockArray ( )
static

Creates a new array which uses an internal BlockArray implementation. Not all element types are supported. You can use NewPagedArray for a similar implementation which has the possibility to share copy-on-write blocks among several arrays.

Template Parameters
TElement type of the array to create. Not all element types are supported.
Returns
Newly created array.

◆ NewPagedArray() [1/2]

static MAXON_METHOD Result<Array<Generic> > NewPagedArray ( const DataType elementType,
const Generic *  defaultValue = nullptr,
Bool  useRefCountForDefault = false 
)
static

Creates a new array which uses an internal implementation based on copy-on-write pages, see NewPagedArray. You can use this overload when you don't want to provide a base array for default values but just a single default value.

The implementation has to obtain the container type from the given element type. In performance-critical code you should do that yourself outside of the performance-critical part and use the method NewBaseArrayFromContainerType.

Parameters
[in]elementTypeThe element type of the array.
[in]defaultValueA pointer to a value of the given element type. This will be used as default value for non-existing pages. If this is nullptr, the null value of the element type will be used.
[in]useRefCountForDefaultIf true, defaultValue will be held by a strong reference internally. In this case the reference count has to be at least 1 when you call the method.
Returns
Newly created paged array.

◆ NewPagedArrayFromContainerType()

static MAXON_METHOD Result<Array<Generic> > NewPagedArrayFromContainerType ( const ContainerDataType<> &  containerType,
const Generic *  defaultValue = nullptr,
Bool  useRefCountForDefault = false 
)
static

Creates a new array which uses an internal implementation based on copy-on-write pages, see NewPagedArray. You can use this overload when you don't want to provide a base array for default values but just a single default value.

This method requires to pass the container type instead of the element type, but it's faster than NewPagedArray. To obtain the container type from an element type, you can use this code:

ContainerDataType<> t = ParametricTypes::ContainerInterface().Instantiate(elementType) iferr_return;
Parameters
[in]containerTypeThe container type of the array.
[in]defaultValueA pointer to a value of the given element type. This will be used as default value for non-existing pages. If this is nullptr, the null value of the element type will be used.
[in]useRefCountForDefaultIf true, defaultValue will be held by a strong reference internally. In this case the reference count has to be at least 1 when you call the method.
Returns
Newly created paged array.

◆ NewPagedArray() [2/2]

static Result<Array<T> > NewPagedArray ( )
static

Creates a new array which uses an internal implementation based on copy-on-write pages, see NewPagedArray.

Template Parameters
TElement type of the array to create.
Returns
Newly created paged array.

◆ Slice() [1/3]

static MAXON_METHOD Result<Array<Generic> > Slice ( const Array< Generic > &  base,
Int  start,
Int  end,
Bool  cycle,
const Generic *  defaultValue = nullptr,
Bool  useRefCountForDefault = false 
)
static

Creates a new array which is a slice (or even an extension) of a given base array.

For a usual slice start and end index are within the index range of the underlying base array. E.g. if the base array has the four elements ABCD, start is 1 and end is 3, the slice has two elements BC.

But you can also extend the base array at its ends. If we change start to -2 and end to 9 in the previous example, there are two extra elements before the base array and 5 behind. The extra elements are filled as follows:

  • If cycle is true, the base array is repeated, so in the example we get the elements CDABCDABCDA.
  • Otherwise, if there's a default value, this is used, so in the example we get XXABCDXXXXX where X is the default value.
  • Otherwise the first and last element of the base are repeated, so we get AAABCDDDDDD.
Parameters
[in]baseThe base array from where elements shall be obtained.
[in]startThe start index within base (inclusive), can be negative.
[in]endThe end index within base (exclusive), can be larger than the size of base.
[in]cycleTrue if the base array shall be repeated to obtain values outside of the original index range of the base.
[in]defaultValueA pointer to a value of the given element type. This will be used as default value for indices outside of the original index range of the base. If this is nullptr, the first and last element of the base are repeated for indices outside of the original index range of the base.
[in]useRefCountForDefaultIf true, defaultValue will be held by a strong reference internally. In this case the reference count has to be at least 1 when you call the method.
Returns
Newly created sliced array.

◆ Slice() [2/3]

static Result<Array<T> > Slice ( const Array< T > &  base,
Int  start,
Int  end 
)
static

Creates a new array which is a slice of a given base array, see Slice.

Parameters
[in]baseThe base array from where elements shall be obtained.
[in]startThe start index within base (inclusive), has to be within the index range of base.
[in]endThe end index within base (exclusive), has to be within the index range of base.
Returns
Newly created sliced array.

◆ Slice() [3/3]

static Result<Array<T> > Slice ( const Array< T > &  base,
Int  start,
Int  end,
Bool  cycle,
const T *  defaultValue = nullptr,
Bool  useRefCountForDefault = false 
)
static

Creates a new array which is a slice (or even an extension) of a given base array, see Slice.

Parameters
[in]baseThe base array from where elements shall be obtained.
[in]startThe start index within base (inclusive), can be negative.
[in]endThe end index within base (exclusive), can be larger than the size of base.
[in]cycleTrue if the base array shall be repeated to obtain values outside of the original index range of the base.
[in]defaultValueA pointer to a value of the given element type. This will be used as default value for indices outside of the original index range of the base. If this is nullptr, the first and last element of the base are repeated for indices outside of the original index range of the base.
[in]useRefCountForDefaultIf true, defaultValue will be held by a strong reference internally. In this case the reference count has to be at least 1 when you call the method.
Template Parameters
TElement type of the array to create.
Returns
Newly created sliced array.

◆ NewSingleValueArray() [1/2]

static MAXON_METHOD Result<Array<Generic> > NewSingleValueArray ( const ConstDataPtr value,
Int  count,
const ContainerDataType<> &  containerType = GetPtrSizedZeroRefContainerDataType<>>() 
)
static

Creates a new array where all elements have the same single value. This saves memory because only a single element has to be allocated.

To improve performance you can pass the array's container type to the optional parameter containerType. To obtain the container type from an element type, you can use this code:

ContainerDataType<> t = ParametricTypes::ContainerInterface().Instantiate(elementType) iferr_return;
Parameters
[in]valueThe value to use for the array.
[in]countThe size of the array. The value will be repeated count times, but without the need to make an allocation for that many elements.
[in]containerTypeThe container type of the array. Can be a null reference, then the container type will be constructed from the value's type.
Returns
Newly created array.

◆ NewSingleValueArray() [2/2]

static Result<Array<T> > NewSingleValueArray ( const T &  value,
Int  count 
)
static

Creates a new array where all elements have the same single value. This saves memory because only a single element has to be allocated.

Parameters
[in]valueThe value to use for the array.
[in]countThe size of the array. The value will be repeated count times, but without the need to make an allocation for that many elements.
Template Parameters
TElement type of the array to create.
Returns
Newly created array.

◆ ExtractMember() [1/2]

static MAXON_METHOD Result<Array<Generic> > ExtractMember ( const Array< Generic > &  base,
Int  offset,
const ContainerDataType<> &  containerType 
)
static

Creates a new array where the elements are members of the elements of an underlying array. For example if the underlying array has elements of type Vector, you can extract the x, y and z members as arrays without the need to allocate memory for the extracted elements, because the memory of the underlying array will be used. You'd have to pass 0, sizeof(Float), or 2*sizeof(Float) to the offset parameter for x, y or z, respectively. From a Vector array you could also extract xy or yz as a Vector2d array, but not xz due to the memory layout of the Vector class.

The method expects the container type of the new array as parameter. To obtain the container type from an element type, you can use this code:

ContainerDataType<> t = ParametricTypes::ContainerInterface().Instantiate(elementType) iferr_return;
Parameters
[in]baseThe base array from where elements shall be obtained.
[in]offsetThe offset (in bytes) of the member within the element type of the base array.
[in]containerTypeThe container type of the array.
Returns
Newly created array.

◆ ExtractMember() [2/2]

static Result<Array<DST> > ExtractMember ( const Array< SRC > &  base,
Int  offset 
)
static

Creates a new array where the elements are members of the elements of an underlying array, see ExtractMember.

Parameters
[in]baseThe base array from where elements shall be obtained.
[in]offsetThe offset (in bytes) of the member within the element type of the base array.
Template Parameters
DSTType of the member.
SRCElement type of the base array. Usually this template parameter is deduced by the compiler.
Returns
Newly created array.

◆ Reinterpret() [1/2]

static MAXON_METHOD Result<Array<Generic> > Reinterpret ( const Array< Generic > &  base,
const ContainerDataType<> &  containerType 
)
static

Creates a new array where the elements are taken from an underlying array, but interpreted as a different type. The types have to be compatible regarding their memory layout, constructors and destructors. For example Vector and Color or ObjectRef and InputStreamRef are compatible, but ObjectRef and ObjectInterface* aren't. No new memory for the elements will be allocated.

The returned new array will hold a strong reference on the base array unless the base is a paged array: Then a clone of the base is returned (so that pages are shared) but with the new type.

If you want to reinterpret array elements when memory layout is compatible, but constructors or destructors aren't (such as for the case ObjectRef and ObjectInterface*), you can use the ExtractMember method with an offset of 0.

The method expects the container type of the new array as parameter. To obtain the container type from an element type, you can use this code:

ContainerDataType<> t = ParametricTypes::ContainerInterface().Instantiate(elementType) iferr_return;
Parameters
[in]baseThe base array from where elements shall be obtained.
[in]containerTypeThe container type of the array.
Returns
Newly created array.

◆ Reinterpret() [2/2]

static Result<Array<DST> > Reinterpret ( const Array< SRC > &  base)
static

Creates a new array where the elements are taken from an underlying array, but interpreted as a different type, see Reinterpret.

Parameters
[in]baseThe base array from where elements shall be obtained.
Template Parameters
DSTElement type of the array to create.
SRCElement type of the base array. Usually this template parameter is deduced by the compiler.
Returns
Newly created array.

◆ PrivateNewPagedArrayFromBase() [1/2]

static MAXON_METHOD Result<Array<Generic> > PrivateNewPagedArrayFromBase ( const Array< Generic > &  base,
const Generic *  defaultValue = nullptr,
Bool  useRefCountForDefault = false 
)
static

Creates a new array which uses an internal implementation based on copy-on-write pages. This implementation has the following features:

  • The array elements are stored in pages of fixed size.
  • Pages are copy-on-write, which means that they can be shared among several paged arrays (e.g. when you make a copy of a paged array).
  • Pages are allocated when needed for write access. Whenever there is no page yet for a read access to an index range, an underlying base array is used instead, or a default element value. Thus paged arrays can be used for sparse arrays.
Warning
In general write access is NOT thread-safe because of the page management. However you can call the MakeElementsWritable method in advance to ensure that an index range is directly writable (no further need of page allocation). Afterwards write access to the index range is thread-safe.
Parameters
[in]baseThe base array from where elements shall be obtained when the paged array itself hasn't set values for the elements yet.
[in]defaultValueA pointer to a value of the given element type. This will be used as default value for non-existing pages. If this is nullptr, the null value of the element type will be used.
[in]useRefCountForDefaultIf true, defaultValue will be held by a strong reference internally. In this case the reference count has to be at least 1 when you call the method.
Returns
Newly created paged array.

◆ PrivateNewPagedArrayFromBase() [2/2]

static Result<Array<T> > PrivateNewPagedArrayFromBase ( const Array< T > &  base)
static

Creates a new array which uses an internal implementation based on copy-on-write pages, see NewPagedArray.

Parameters
[in]baseThe base array from where elements shall be obtained when the paged array itself hasn't set values for the elements yet.
Template Parameters
TElement type of the array to create.
Returns
Newly created paged array.

◆ ConvertToSingleBlock() [1/2]

static MAXON_METHOD Result<Array<Generic> > ConvertToSingleBlock ( const Array< Generic > &  source)
static

Converts the source array to an array which uses a single memory block with default stride. In other words, the block returned by {array.GetBlock(0, block)} represents the whole array.

If the source array already fulfills that condition, it is returned directly.

Parameters
[in]sourceThe array to convert to single block array.
Returns
Converted array, it's guaranteed to consist of exactly one block.

◆ ConvertToSingleBlock() [2/2]

static Result<Array<T> > ConvertToSingleBlock ( const Array< T > &  source)
static

Converts the source array to an array which uses a single memory block with default stride. In other words, the block returned by {array.GetBlock(0, block)} represents the whole array.

If the source array already fulfills that condition, it is returned directly.

Parameters
[in]sourceThe array to convert to single block array.
Returns
Converted array, it's guaranteed to consist of exactly one block.