//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-#include <RCSResourceAttributes.h>
+#include "RCSResourceAttributes.h"
-#include <ResourceAttributesUtils.h>
-#include <ResourceAttributesConverter.h>
+#include <sstream>
-#include <boost/lexical_cast.hpp>
-#include <boost/mpl/advance.hpp>
-#include <boost/mpl/size.hpp>
-#include <boost/mpl/deref.hpp>
+#include "ResourceAttributesUtils.h"
+#include "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 >
+ class ToStringVisitor: public boost::static_visitor<>
{
public:
ToStringVisitor() = default;
ToStringVisitor& operator=(const ToStringVisitor&) = delete;
ToStringVisitor& operator=(ToStringVisitor&&) = delete;
- template < typename T >
- std::string operator()(const T& value) const
+ template< typename T >
+ void operator()(const T& value)
{
- return boost::lexical_cast<std::string>(value);
+ m_stream << boost::lexical_cast< std::string >(value);
}
- std::string operator()(std::nullptr_t) const
+ template< typename T >
+ void operator()(const std::vector< T >& v)
{
- return "";
+ m_stream << "[";
+ for (auto it = v.begin(); it != v.end(); ++it)
+ {
+ if (it != v.begin()) m_stream << ", ";
+ (*this)(*it);
+ }
+ m_stream << "]";
}
- std::string operator()(bool value) const
+ void operator()(std::nullptr_t)
{
- return value ? "true" : "false";
+ m_stream << "";
}
- std::string operator()(const std::string& value) const
+ void operator()(bool value)
{
- return value;
+ m_stream << (value ? "true" : "false");
}
- std::string operator()(const OIC::Service::RCSResourceAttributes&) const
+ void operator()(const std::string& value)
{
- return "Attributes";
+ m_stream << "\"" + value + "\"";
+ }
+
+ void operator()(const RCSByteString& value)
+ {
+ for (size_t i = 0; i < value.size(); ++i)
+ {
+ m_stream << "\\x" << std::hex << (int)value[i];
+ }
+ }
+
+ void operator()(const RCSResourceAttributes& attrs)
+ {
+ m_stream << "{";
+ for (auto it = attrs.begin(); it != attrs.end(); ++it)
+ {
+ if (it != attrs.begin()) m_stream << ", ";
+ m_stream << "\"" << it->key() << "\" : " << it->value().toString();
+ }
+ m_stream << "}";
+ }
+
+ std::string get() const {
+ return m_stream.str();
}
+
+ private:
+ std::ostringstream m_stream;
};
class TypeVisitor: public boost::static_visitor< RCSResourceAttributes::Type >
};
template< >
+ struct TypeInfoConverter< RCSByteString >
+ {
+ static constexpr RCSResourceAttributes::TypeId typeId =
+ RCSResourceAttributes::TypeId::BYTESTRING;
+ };
+
+ template< >
struct TypeInfoConverter< RCSResourceAttributes >
{
static constexpr RCSResourceAttributes::TypeId typeId =
RCSResourceAttributes::TypeId::ATTRIBUTES;
};
+ template< typename T >
+ struct TypeInfoConverter< std::vector< T > >
+ {
+ static constexpr RCSResourceAttributes::TypeId typeId =
+ RCSResourceAttributes::TypeId::VECTOR;
+ };
+
+ template< typename T >
+ struct SequenceTraits
+ {
+ static constexpr size_t depth = 0;
+ typedef T base_type;
+ };
+
+ template< typename T >
+ struct SequenceTraits< std::vector< T > >
+ {
+ static constexpr size_t depth = SequenceTraits< T >::depth + 1;
+ typedef typename SequenceTraits< T >::base_type base_type;
+ };
+
struct TypeInfo
{
- RCSResourceAttributes::TypeId typeId;
+ RCSResourceAttributes::TypeId m_typeId;
+ RCSResourceAttributes::Type m_baseType;
+ size_t m_depth;
- template< typename TRAIT >
- constexpr TypeInfo(TRAIT) :
- typeId{ TRAIT::typeId }
+ template< typename T, typename ST = SequenceTraits < T > >
+ constexpr static TypeInfo get()
{
+ return { TypeInfoConverter< T >::typeId ,
+ RCSResourceAttributes::Type::typeOf< typename ST::base_type >(), ST::depth };
}
template< typename VARIANT, int POS >
- static constexpr TypeInfo get()
+ constexpr static 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 >{ });
+ typedef typename boost::mpl::begin< typename VARIANT::types >::type mpl_begin;
+ typedef typename boost::mpl::advance< mpl_begin, boost::mpl::int_< POS > >::type iter;
+
+ return get< typename boost::mpl::deref< iter >::type >();
}
};
template< typename VARIANT, int POS >
- constexpr inline std::vector< TypeInfo > getTypeInfo(Int2Type< POS >) noexcept
+ inline std::vector< TypeInfo > getTypeInfo(Int2Type< POS >) noexcept
{
- auto&& vec = getTypeInfo< VARIANT >(Int2Type< POS - 1 >{ });
+ 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 >) noexcept
+ inline std::vector< TypeInfo > getTypeInfo(Int2Type< 0 >) noexcept
{
return { TypeInfo::get< VARIANT, 0 >() };
}
template< typename VARIANT >
inline TypeInfo getTypeInfo(int which) noexcept
{
- static constexpr int variantEnd = boost::mpl::size< typename VARIANT::types >::value - 1;
+ static constexpr size_t variantSize = boost::mpl::size< typename VARIANT::types >::value;
+ static constexpr size_t variantEnd = variantSize - 1;
static const std::vector< TypeInfo > typeInfos = getTypeInfo< VARIANT >(
Int2Type< variantEnd >{ });
+ static_assert(variantSize > 0, "Variant has no type!");
+
return typeInfos[which];
}
-
} // unnamed namespace
{
namespace Service
{
-
RCSResourceAttributes::Value::ComparisonHelper::ComparisonHelper(const Value& v) :
m_valueRef(v)
{
auto RCSResourceAttributes::Type::getId() const noexcept -> TypeId
{
- return ::getTypeInfo< ValueVariant >(m_which).typeId;
+ return ::getTypeInfo< ValueVariant >(m_which).m_typeId;
}
+ auto RCSResourceAttributes::Type::getBaseTypeId(const Type& t) noexcept -> TypeId
+ {
+ return ::getTypeInfo< ValueVariant >(t.m_which).m_baseType.getId();
+ }
+
+ size_t RCSResourceAttributes::Type::getDepth(const Type& t) noexcept
+ {
+ return ::getTypeInfo< ValueVariant >(t.m_which).m_depth;
+ }
+
+
RCSResourceAttributes::Value::Value() :
m_data{ new ValueVariant{} }
{
std::string RCSResourceAttributes::Value::toString() const
{
- return boost::apply_visitor(ToStringVisitor(), *m_data);
+ ToStringVisitor visitor;
+ boost::apply_visitor(visitor, *m_data);
+ return visitor.get();
}
void RCSResourceAttributes::Value::swap(Value& rhs) noexcept
-> result_type
{
// should not reach here.
- throw BadGetException("");
+ throw RCSBadGetException("");
}
auto RCSResourceAttributes::KeyValuePair::ConstValueVisitor::operator()(
{
}
+ RCSResourceAttributes::iterator::iterator(const iterator& rhs) :
+ m_cur{ rhs.m_cur },
+ m_keyValuePair{ this }
+ {
+ }
+
+ auto RCSResourceAttributes::iterator::operator=(const iterator& rhs) -> iterator&
+ {
+ m_cur = rhs.m_cur;
+ return *this;
+ }
+
RCSResourceAttributes::iterator::iterator(base_iterator&& iter) :
m_cur{ std::move(iter) },
m_keyValuePair{ this }
{
}
+ RCSResourceAttributes::const_iterator::const_iterator(const const_iterator& rhs) :
+ m_cur{ rhs.m_cur }, m_keyValuePair{ this }
+ {
+ }
+
RCSResourceAttributes::const_iterator::const_iterator(
const RCSResourceAttributes::iterator& iter) :
m_cur{ iter.m_cur }, m_keyValuePair{ this }
}
auto RCSResourceAttributes::const_iterator::operator=(
+ const const_iterator& rhs) -> const_iterator&
+ {
+ m_cur = rhs.m_cur;
+ return *this;
+ }
+
+ auto RCSResourceAttributes::const_iterator::operator=(
const RCSResourceAttributes::iterator& iter) -> const_iterator&
{
m_cur = iter.m_cur;
}
catch (const std::out_of_range&)
{
- throw InvalidKeyException{ "No attribute named '" + key + "'" };
+ throw RCSInvalidKeyException{ "No attribute named '" + key + "'" };
}
}
}
catch (const std::out_of_range&)
{
- throw InvalidKeyException{ "No attribute named '" + key + "'" };
+ throw RCSInvalidKeyException{ "No attribute named '" + key + "'" };
}
}
return m_values.erase(key) == 1U;
}
+ auto RCSResourceAttributes::erase(const_iterator pos) -> iterator
+ {
+ return iterator{ m_values.erase(pos.m_cur) };
+ }
+
bool RCSResourceAttributes::contains(const std::string& key) const
{
return m_values.find(key) != m_values.end();