class ResourceAttributes
{
private:
- template< typename T > struct is_supported_type_helper;
+ template< typename T > struct IsSupportedTypeHelper;
using ValueVariant = boost::variant<
std::nullptr_t,
template< typename T, typename V = void >
using enable_if_supported = typename std::enable_if<
- is_supported_type_helper< T >::type::value, V >::type;
+ IsSupportedTypeHelper< T >::type::value, V >::type;
template< typename T, typename V = void >
using enable_if_unsupported = typename std::enable_if<
- !is_supported_type_helper< T >::type::value, V >::type;
+ !IsSupportedTypeHelper< T >::type::value, V >::type;
template< typename VISITOR >
class KeyValueVisitorHelper: public boost::static_visitor< >
VISITOR& m_visitor;
};
+ template <typename T> struct IndexOfType;
+
public:
template< typename T >
- using is_supported_type = typename is_supported_type_helper< T >::type;
+ using is_supported_type = typename IsSupportedTypeHelper< T >::type;
+
+ enum class TypeId
+ {
+ NULL_T,
+ INT,
+ DOUBLE,
+ BOOL,
+ STRING,
+ ATTRIBUTES,
+ VECTOR
+ };
+
+ class Type
+ {
+ public:
+ Type(const Type&) = default;
+ Type(Type&&) = default;
+
+ Type& operator=(const Type&) = default;
+ Type& operator=(Type&&) = default;
+
+ TypeId getId() const;
+
+ template < typename T >
+ static Type typeOf(const T& value)
+ {
+ return Type(value);
+ }
+
+ friend bool operator==(const Type&, const Type&);
+
+ private:
+ template < typename T >
+ explicit Type(const T&) :
+ m_which{ IndexOfType< T >::value }
+ {
+ }
+
+ private:
+ int m_which;
+ };
class Value
{
return checkedGet< T >();
}
- bool isTypeEqualWith(const Value& rhs) const
- {
- return m_data->which() == rhs.m_data->which();
- }
-
- template< typename T >
- enable_if_supported< T, bool > isTypeOf() const
- {
- using iter = typename boost::mpl::find< ValueVariant::types, T >::type;
-
- return m_data->which()
- == boost::mpl::distance< mpl_begin< ValueVariant::types >, iter >::value;
- }
-
- template< typename T >
- enable_if_unsupported< T, bool > isTypeOf() const
- {
- return false;
- }
+ Type getType() const;
std::string toString() const;
friend class ResourceAttributesConverter;
};
- template< typename T > struct ResourceAttributes::is_supported_type_helper
+ template< typename T >
+ struct ResourceAttributes::IsSupportedTypeHelper
{
using type = boost::mpl::contains<ValueVariant::types, typename std::decay< T >::type>;
};
+ template <typename T>
+ struct ResourceAttributes::IndexOfType
+ {
+ using iter = typename boost::mpl::find< ValueVariant::types, T >::type;
+
+ static constexpr int value = boost::mpl::distance< mpl_begin< ValueVariant::types >,
+ iter >::value;
+ };
+ bool operator==(const ResourceAttributes::Type&, const ResourceAttributes::Type&);
+ bool operator!=(const ResourceAttributes::Type&, const ResourceAttributes::Type&);
bool operator!=(const ResourceAttributes::Value&, const ResourceAttributes::Value&);
#include <internal/ResourceAttributesConverter.h>
#include <boost/lexical_cast.hpp>
+#include <boost/mpl/advance.hpp>
+#include <boost/mpl/size.hpp>
+#include <boost/mpl/deref.hpp>
namespace
{
+ using namespace OIC::Service;
+
class ToStringVisitor: public boost::static_visitor< std::string >
{
public:
}
};
+ class TypeVisitor: public boost::static_visitor< ResourceAttributes::Type >
+ {
+ public:
+ TypeVisitor() = default;
+ TypeVisitor(const TypeVisitor&) = delete;
+ TypeVisitor(TypeVisitor&&) = delete;
+
+ TypeVisitor& operator=(const TypeVisitor&) = delete;
+ TypeVisitor& operator=(TypeVisitor&&) = delete;
+
+ template< typename T >
+ ResourceAttributes::Type operator()(const T& value) const
+ {
+ return ResourceAttributes::Type::typeOf(value);
+ }
+
+ };
+
+ template< int >
+ struct Int2Type {};
+
+ template< typename T >
+ struct TypeInfoConverter;
+
+ template< >
+ struct TypeInfoConverter< int >
+ {
+ static constexpr ResourceAttributes::TypeId typeId = ResourceAttributes::TypeId::INT;
+ };
+
+ template< >
+ struct TypeInfoConverter< std::nullptr_t >
+ {
+ static constexpr ResourceAttributes::TypeId typeId = ResourceAttributes::TypeId::NULL_T;
+ };
+
+ template< >
+ struct TypeInfoConverter< double >
+ {
+ static constexpr ResourceAttributes::TypeId typeId = ResourceAttributes::TypeId::DOUBLE;
+ };
+
+ template< >
+ struct TypeInfoConverter< bool >
+ {
+ static constexpr ResourceAttributes::TypeId typeId = ResourceAttributes::TypeId::BOOL;
+ };
+
+ template< >
+ struct TypeInfoConverter< std::string >
+ {
+ static constexpr ResourceAttributes::TypeId typeId = ResourceAttributes::TypeId::STRING;
+ };
+
+ template< >
+ struct TypeInfoConverter< ResourceAttributes >
+ {
+ static constexpr ResourceAttributes::TypeId typeId = ResourceAttributes::TypeId::ATTRIBUTES;
+ };
+
+ struct TypeInfo
+ {
+ ResourceAttributes::TypeId typeId;
+
+ template< typename TRAIT >
+ constexpr TypeInfo(TRAIT) :
+ typeId{ TRAIT::typeId }
+ {
+ }
+
+ template< typename VARIANT, int POS >
+ static constexpr TypeInfo get()
+ {
+ return TypeInfo(
+ TypeInfoConverter<
+ typename boost::mpl::deref<
+ typename boost::mpl::advance<
+ typename boost::mpl::begin< typename VARIANT::types >::type,
+ boost::mpl::int_< POS > >::type >::type >{ });
+ }
+ };
+
+ template< typename VARIANT, int POS >
+ constexpr inline std::vector< TypeInfo > getTypeInfo(Int2Type< POS >)
+ {
+ auto&& vec = getTypeInfo< VARIANT >(Int2Type< POS - 1 >{ });
+ vec.push_back(TypeInfo::get< VARIANT, POS >());
+ return vec;
+ }
+
+ template< typename VARIANT >
+ constexpr inline std::vector< TypeInfo > getTypeInfo(Int2Type< 0 >)
+ {
+ return { TypeInfo::get< VARIANT, 0 >() };
+ }
+
+ template< typename VARIANT >
+ inline TypeInfo getTypeInfo(int which)
+ {
+ static constexpr int variantEnd = boost::mpl::size< typename VARIANT::types >::value - 1;
+ static const std::vector< TypeInfo > typeInfos = getTypeInfo< VARIANT >(
+ Int2Type< variantEnd >{ });
+
+ return typeInfos[which];
+ }
+
} // unnamed namespace
namespace Service
{
+ bool operator==(const ResourceAttributes::Type& lhs, const ResourceAttributes::Type& rhs)
+ {
+ return lhs.m_which == rhs.m_which;
+ }
+
+ bool operator!=(const ResourceAttributes::Type& lhs, const ResourceAttributes::Type& rhs)
+ {
+ return !(lhs == rhs);
+ }
+
bool operator!=(const ResourceAttributes::Value& lhs, const ResourceAttributes::Value& rhs)
{
return !(lhs == rhs);
return !(rhs == lhs);
}
-
bool operator==(const char* lhs, const ResourceAttributes::Value& rhs)
{
return rhs == lhs;
return !(lhs == rhs);
}
+ auto ResourceAttributes::Type::getId() const -> TypeId
+ {
+ return ::getTypeInfo< ValueVariant >(m_which).typeId;
+ }
+
ResourceAttributes::Value::Value() :
m_data{ new ValueVariant{} }
{
return equals< std::string >(rhs);
}
+ auto ResourceAttributes::Value::getType() const -> Type
+ {
+ return boost::apply_visitor(TypeVisitor(), *m_data);
+ }
+
std::string ResourceAttributes::Value::toString() const
{
return boost::apply_visitor(ToStringVisitor(), *m_data);
return boost::apply_visitor(m_valueVisitor, m_iterRef);
}
-
ResourceAttributes::KeyValuePair::KeyValuePair(boost::variant<iterator*,
const_iterator*>&& ref) :
m_iterRef{ ref }
bool acceptableAttributeValue(const ResourceAttributes::Value& dest,
const ResourceAttributes::Value& value)
{
- if (!dest.isTypeEqualWith(value))
+ if (dest.getType() != value.getType())
{
return false;
}
static_assert(ResourceAttributes::is_supported_type< ResourceAttributes >::value,
"ResourceAttributes doesn't have ResourceAttributes recursively.");
- if (dest.isTypeOf< ResourceAttributes >()
+ if (dest.getType().getId() == ResourceAttributes::TypeId::ATTRIBUTES
&& !acceptableAttributes(dest.get< ResourceAttributes >(),
value.get< ResourceAttributes >()))
{