14 #include <mapbox/compatibility/value.hpp>
19 #include <type_traits>
91 namespace conversion {
94 class ConversionTraits;
101 static_assert(
sizeof(Storage) >=
sizeof(std::decay_t<T>),
"Storage must be large enough to hold value type");
102 new (
static_cast<void*
>(&storage)) std::decay_t<T>(std::forward<T>(value));
107 vtable->move(std::move(v.storage), storage);
111 vtable->destroy(storage);
116 vtable->destroy(storage);
119 vtable->move(std::move(v.storage), storage);
130 return v.vtable->isUndefined(v.storage);
135 return v.vtable->isArray(v.storage);
140 return v.vtable->arrayLength(v.storage);
145 return v.vtable->arrayMember(v.storage, i);
150 return v.vtable->isObject(v.storage);
155 return v.vtable->objectMember(v.storage, name);
160 return v.vtable->eachMember(v.storage, fn);
165 return v.vtable->toBool(v.storage);
170 return v.vtable->toNumber(v.storage);
175 return v.vtable->toDouble(v.storage);
180 return v.vtable->toString(v.storage);
185 return v.vtable->toValue(v.storage);
190 return v.vtable->toGeoJSON(v.storage,
error);
196 using Storage = std::aligned_storage_t<32, 8>;
199 using Storage = std::aligned_storage_t<32, 8>;
203 using Storage = std::aligned_storage_t<8, 8>;
207 void (*move) (Storage&& src, Storage& dest);
208 void (*destroy) (Storage&);
212 bool (*
isArray) (
const Storage&);
217 std::optional<Convertible> (*
objectMember) (
const Storage&,
const char *);
220 std::optional<bool> (*
toBool) (
const Storage&);
221 std::optional<float> (*
toNumber) (
const Storage&);
222 std::optional<double> (*
toDouble) (
const Storage&);
223 std::optional<std::string> (*
toString) (
const Storage&);
224 std::optional<Value> (*
toValue) (
const Storage&);
232 template <
typename T>
233 static auto vtableEachMember(
const Storage& s,
const std::function<std::optional<Error>(
const std::string&,
const Convertible&)>& fn) {
234 return ConversionTraits<T>::eachMember(
reinterpret_cast<const T&
>(s), [&](
const std::string& k, T&& v) {
239 template <
typename T>
240 static VTable* vtableForType() {
241 using Traits = ConversionTraits<T>;
242 static VTable vtable = {
243 [] (Storage&& src, Storage& dest) {
244 new (
static_cast<void*
>(&dest)) T(
reinterpret_cast<T&&
>(src));
247 reinterpret_cast<T&
>(s).~T();
249 [] (
const Storage& s) {
250 return Traits::isUndefined(
reinterpret_cast<const T&
>(s));
252 [] (
const Storage& s) {
253 return Traits::isArray(
reinterpret_cast<const T&
>(s));
255 [] (
const Storage& s) {
256 return Traits::arrayLength(
reinterpret_cast<const T&
>(s));
258 [] (
const Storage& s, std::size_t i) {
259 return Convertible(Traits::arrayMember(
reinterpret_cast<const T&
>(s), i));
261 [] (
const Storage& s) {
262 return Traits::isObject(
reinterpret_cast<const T&
>(s));
264 [] (
const Storage& s,
const char * key) {
265 std::optional<T> member = Traits::objectMember(
reinterpret_cast<const T&
>(s), key);
267 return std::optional<Convertible>(
Convertible(std::move(*member)));
269 return std::optional<Convertible>();
273 [] (
const Storage& s) {
274 return Traits::toBool(
reinterpret_cast<const T&
>(s));
276 [] (
const Storage& s) {
277 return Traits::toNumber(
reinterpret_cast<const T&
>(s));
279 [] (
const Storage& s) {
280 return Traits::toDouble(
reinterpret_cast<const T&
>(s));
282 [] (
const Storage& s) {
285 [] (
const Storage& s) {
286 return Traits::toValue(
reinterpret_cast<const T&
>(s));
288 [] (
const Storage& s,
Error& err) {
289 return Traits::toGeoJSON(
reinterpret_cast<const T&
>(s), err);
299 template <
class T,
class...Args>
319 template <
typename T>
320 struct ValueFactory<T, typename
std::enable_if_t<(!std::is_enum_v<T> && !is_linear_container<T>::value)>> {
321 static Value make(
const T& arg) {
return {arg}; }
324 template <
typename T>
325 struct ValueFactory<T, typename
std::enable_if_t<std::is_enum_v<T>>> {
329 template <
typename T>
330 struct ValueFactory<T, typename
std::enable_if_t<is_linear_container<T>::value>> {
331 static Value make(
const T& arg) {
332 mapbox::base::ValueArray result;
333 result.reserve(arg.size());
334 for (
const auto& item : arg) {
335 result.emplace_back(ValueFactory<std::decay_t<decltype(item)>>::make(item));
358 template <
typename T>
363 template <
typename T>
mbgl::Value serialize() const
static const char * toString(T)
const expression::Expression & getExpression() const
std::array< float, 3 > getSpherical() const
auto match(Ts &&... ts) const
double getAngle() const noexcept
Generic representation of a style property.
mapbox::base::Value serialize() const
friend std::optional< std::string > toString(const Convertible &v)
friend bool isObject(const Convertible &v)
friend std::optional< bool > toBool(const Convertible &v)
Convertible & operator=(Convertible &&v) noexcept
friend std::optional< Value > toValue(const Convertible &v)
Convertible(const Convertible &)=delete
Convertible(Convertible &&v) noexcept
friend std::optional< GeoJSON > toGeoJSON(const Convertible &v, Error &error)
friend std::optional< Convertible > objectMember(const Convertible &v, const char *name)
friend std::optional< Error > eachMember(const Convertible &v, const std::function< std::optional< Error >(const std::string &, const Convertible &)> &fn)
friend bool isArray(const Convertible &v)
friend Convertible arrayMember(const Convertible &v, std::size_t i)
friend std::optional< double > toDouble(const Convertible &v)
friend bool isUndefined(const Convertible &v)
friend std::optional< float > toNumber(const Convertible &v)
friend std::size_t arrayLength(const Convertible &v)
Convertible & operator=(const Convertible &)=delete
virtual mbgl::Value serialize() const
StyleProperty makeStyleProperty(const PropertyValue< T > &value)
std::optional< T > convert(const Convertible &value, Error &error, Args &&...args)
std::unique_ptr< Expression > error(std::string)
std::unique_ptr< Expression > toString(std::unique_ptr< Expression >, std::unique_ptr< Expression > def=nullptr)
std::unique_ptr< Expression > string(std::unique_ptr< Expression >, std::unique_ptr< Expression > def=nullptr)
constexpr ErrorType Error
mapbox::base::Value Value
static Value make(const ColorRampPropertyValue &value)
static Value make(const Color &color)
static Value make(const Position &position)
static Value make(const Rotation &rotation)
static Value make(const TransitionOptions &value)
static Value make(float f)