boost/json/detail/value.hpp
//
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/boostorg/json
//
#ifndef BOOST_JSON_DETAIL_VALUE_HPP
#define BOOST_JSON_DETAIL_VALUE_HPP
#include <boost/json/fwd.hpp>
#include <boost/json/kind.hpp>
#include <boost/json/storage_ptr.hpp>
#include <cstdint>
#include <limits>
#include <new>
#include <utility>
namespace boost {
namespace json {
namespace detail {
struct key_t
{
};
#if 0
template<class T>
struct to_number_limit
: std::numeric_limits<T>
{
};
template<class T>
struct to_number_limit<T const>
: to_number_limit<T>
{
};
template<>
struct to_number_limit<long long>
{
static constexpr long long (min)() noexcept
{
return -9223372036854774784;
}
static constexpr long long (max)() noexcept
{
return 9223372036854774784;
}
};
template<>
struct to_number_limit<unsigned long long>
{
static constexpr
unsigned long long (min)() noexcept
{
return 0;
}
static constexpr
unsigned long long (max)() noexcept
{
return 18446744073709549568ULL;
}
};
#else
template<class T>
class to_number_limit
{
// unsigned
static constexpr
double min1(std::false_type)
{
return 0.0;
}
static constexpr
double max1(std::false_type)
{
return max2u(std::integral_constant<
bool, (std::numeric_limits<T>::max)() ==
UINT64_MAX>{});
}
static constexpr
double max2u(std::false_type)
{
return static_cast<double>(
(std::numeric_limits<T>::max)());
}
static constexpr
double max2u(std::true_type)
{
return 18446744073709549568.0;
}
// signed
static constexpr
double min1(std::true_type)
{
return min2s(std::integral_constant<
bool, (std::numeric_limits<T>::max)() ==
INT64_MAX>{});
}
static constexpr
double min2s(std::false_type)
{
return static_cast<double>(
(std::numeric_limits<T>::min)());
}
static constexpr
double min2s(std::true_type)
{
return -9223372036854774784.0;
}
static constexpr
double max1(std::true_type)
{
return max2s(std::integral_constant<
bool, (std::numeric_limits<T>::max)() ==
INT64_MAX>{});
}
static constexpr
double max2s(std::false_type)
{
return static_cast<double>(
(std::numeric_limits<T>::max)());
}
static constexpr
double max2s(std::true_type)
{
return 9223372036854774784.0;
}
public:
static constexpr
double (min)() noexcept
{
return min1(std::is_signed<T>{});
}
static constexpr
double (max)() noexcept
{
return max1(std::is_signed<T>{});
}
};
#endif
struct scalar
{
storage_ptr sp; // must come first
kind k; // must come second
union
{
bool b;
std::int64_t i;
std::uint64_t u;
double d;
};
explicit
scalar(storage_ptr sp_ = {}) noexcept
: sp(std::move(sp_))
, k(json::kind::null)
{
}
explicit
scalar(bool b_,
storage_ptr sp_ = {}) noexcept
: sp(std::move(sp_))
, k(json::kind::bool_)
, b(b_)
{
}
explicit
scalar(std::int64_t i_,
storage_ptr sp_ = {}) noexcept
: sp(std::move(sp_))
, k(json::kind::int64)
, i(i_)
{
}
explicit
scalar(std::uint64_t u_,
storage_ptr sp_ = {}) noexcept
: sp(std::move(sp_))
, k(json::kind::uint64)
, u(u_)
{
}
explicit
scalar(double d_,
storage_ptr sp_ = {}) noexcept
: sp(std::move(sp_))
, k(json::kind::double_)
, d(d_)
{
}
};
struct access
{
template<class Value, class... Args>
static
Value&
construct_value(Value* p, Args&&... args)
{
return *reinterpret_cast<
Value*>(::new(p) Value(
std::forward<Args>(args)...));
}
template<class KeyValuePair, class... Args>
static
KeyValuePair&
construct_key_value_pair(
KeyValuePair* p, Args&&... args)
{
return *reinterpret_cast<
KeyValuePair*>(::new(p)
KeyValuePair(
std::forward<Args>(args)...));
}
template<class Value>
static
char const*
release_key(
Value& jv,
std::size_t& len) noexcept
{
BOOST_ASSERT(jv.is_string());
jv.str_.sp_.~storage_ptr();
return jv.str_.impl_.release_key(len);
}
using index_t = std::uint32_t;
template<class KeyValuePair>
static
index_t&
next(KeyValuePair& e) noexcept
{
return e.next_;
}
template<class KeyValuePair>
static
index_t const&
next(KeyValuePair const& e) noexcept
{
return e.next_;
}
};
BOOST_JSON_DECL
std::size_t
hash_value_impl( value const& jv ) noexcept;
} // detail
} // namespace json
} // namespace boost
#endif