blob: 09b81f9340f8918e221a1f607bba17a5a7c64fab [file] [log] [blame]
/* ----------------------------------------------------------------------- *//**
*
* @file AnyType_proto.hpp
*
*//* ----------------------------------------------------------------------- */
/**
* @brief Class for representing any type.
*
* Instances of this class act a proxy for any arbitrary \ref ConcreteType.
*/
class AnyType : public AbstractType {
// ConcreteType<AnyTypeVector>::getValueByID() accesses mDelegate, so we
// make it a friend
friend class ConcreteType<AnyTypeVector>;
public:
class iterator;
typedef std::back_insert_iterator<AnyTypeVector> insertIterator;
/**
* @brief Conversion constructors
*/
#define EXPAND_TYPE(T) \
AnyType(const T &inValue);
EXPAND_FOR_ALL_TYPES
#undef EXPAND_TYPE
/**
* @brief Constructor for initalization with delegate
*/
AnyType(AbstractTypeSPtr inDelegate) : mDelegate(inDelegate) { }
/**
* @brief The copy constructor: Perform a shallow copy, i.e., copy only
* reference to delegate
*/
AnyType(const AnyType &inValue)
: AbstractType(inValue), mDelegate(inValue.mDelegate) { }
/**
* @brief Constructor for initializing as Null
*/
AnyType(const Null & /* inValue */) { }
/**
* @brief Conversion operators
*
* @internal
* Conversion operators for primitive data types are not without issues.
* In particular, non-sense operations are now syntactically correct.
* E.g., if (anyType1 == anyType2)
*/
#define EXPAND_TYPE(T) \
operator T() const;
EXPAND_FOR_ALL_TYPES
#undef EXPAND_TYPE
bool isCompound() const {
if (mDelegate)
return mDelegate->isCompound();
return AbstractType::isCompound();
}
bool isNull() const {
return !mDelegate;
}
bool isMutable() const {
if (mDelegate)
return mDelegate->isMutable();
return AbstractType::isMutable();
}
unsigned int size() const {
if (mDelegate)
return mDelegate->size();
return AbstractType::size();
}
/**
* @brief Get the element at the given position (0-based).
*
* This function is a convenience wrapper around getValueByID(uint16_t).
*/
AnyType operator[](uint16_t inID) const {
return AnyType(getValueByID(inID));
}
/**
* @brief The default implementation returns an empty smart pointer
*/
AbstractTypeSPtr getValueByID(uint16_t inID) const {
if (mDelegate)
return mDelegate->getValueByID(inID);
return AbstractTypeSPtr();
}
/**
* @brief Clone this instance if it is not mutable, otherwise return this
*/
AnyType cloneIfImmutable() const {
if (isMutable() || !mDelegate)
return *this;
return AnyType(mDelegate->clone());
}
void performCallback(AbstractTypeConverter &inConverter) const {
if (mDelegate)
return mDelegate->performCallback(inConverter);
return AbstractType::performCallback(inConverter);
}
/**
* @brief Return a mutable copy of this variable.
*/
AbstractTypeSPtr clone() const {
if (mDelegate)
return AbstractTypeSPtr(new AnyType(mDelegate->clone()));
return AbstractTypeSPtr(new AnyType(Null()));
}
protected:
/**
* @brief Protected default constructor
*
* We do not want AnyType to be used without explicit initalization in user
* code.
*/
AnyType() {
}
private:
AbstractTypeSPtr mDelegate;
};