Edit: /usr/include/boost/hana/map.hpp (22593B)
/*!
@file
Defines `boost::hana::map`.
@copyright Louis Dionne 2013-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_HANA_MAP_HPP
#define BOOST_HANA_MAP_HPP
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
BOOST_HANA_NAMESPACE_BEGIN
//////////////////////////////////////////////////////////////////////////
// operators
//////////////////////////////////////////////////////////////////////////
namespace detail {
template <>
struct comparable_operators {
static constexpr bool value = true;
};
}
//////////////////////////////////////////////////////////////////////////
// map
//////////////////////////////////////////////////////////////////////////
//! @cond
namespace detail {
template
struct storage_is_default_constructible;
template
struct storage_is_default_constructible> {
static constexpr bool value = detail::fast_and<
BOOST_HANA_TT_IS_CONSTRUCTIBLE(T)...
>::value;
};
template
struct storage_is_copy_constructible;
template
struct storage_is_copy_constructible> {
static constexpr bool value = detail::fast_and<
BOOST_HANA_TT_IS_CONSTRUCTIBLE(T, T const&)...
>::value;
};
template
struct storage_is_move_constructible;
template
struct storage_is_move_constructible> {
static constexpr bool value = detail::fast_and<
BOOST_HANA_TT_IS_CONSTRUCTIBLE(T, T&&)...
>::value;
};
template
struct storage_is_copy_assignable;
template
struct storage_is_copy_assignable> {
static constexpr bool value = detail::fast_and<
BOOST_HANA_TT_IS_ASSIGNABLE(T, T const&)...
>::value;
};
template
struct storage_is_move_assignable;
template
struct storage_is_move_assignable> {
static constexpr bool value = detail::fast_and<
BOOST_HANA_TT_IS_ASSIGNABLE(T, T&&)...
>::value;
};
template
struct map_impl final
: detail::searchable_operators>
, detail::operators::adl>
{
using hash_table_type = HashTable;
using storage_type = Storage;
Storage storage;
using hana_tag = map_tag;
template ::type...>
>::value
>::type>
explicit constexpr map_impl(P&& ...pairs)
: storage{static_cast(pairs)...}
{ }
explicit constexpr map_impl(Storage&& xs)
: storage(static_cast(xs))
{ }
template ::value
>::type>
constexpr map_impl()
: storage()
{ }
template ::value
>::type>
constexpr map_impl(map_impl const& other)
: storage(other.storage)
{ }
template ::value
>::type>
constexpr map_impl(map_impl&& other)
: storage(static_cast(other.storage))
{ }
template ::value
>::type>
constexpr map_impl& operator=(map_impl&& other) {
storage = static_cast(other.storage);
return *this;
}
template ::value
>::type>
constexpr map_impl& operator=(map_impl const& other) {
storage = other.storage;
return *this;
}
// Prevent the compiler from defining the default copy and move
// constructors, which interfere with the SFINAE above.
~map_impl() = default;
};
//! @endcond
template
struct KeyAtIndex {
template
using apply = decltype(hana::first(hana::at_c(std::declval())));
};
template
struct make_map_type {
using Storage = hana::basic_tuple;
using HashTable = typename detail::make_hash_table<
detail::KeyAtIndex::template apply, sizeof...(Pairs)
>::type;
using type = detail::map_impl;
};
}
//////////////////////////////////////////////////////////////////////////
// make
//////////////////////////////////////////////////////////////////////////
template <>
struct make_impl {
template
static constexpr auto apply(Pairs&& ...pairs) {
#if defined(BOOST_HANA_CONFIG_ENABLE_DEBUG_MODE)
static_assert(detail::fast_and::value...>::value,
"hana::make_map(pairs...) requires all the 'pairs' to be Products");
static_assert(detail::fast_and<
hana::Comparable::value...
>::value,
"hana::make_map(pairs...) requires all the keys to be Comparable");
static_assert(detail::fast_and<
hana::Constant<
decltype(hana::equal(hana::first(pairs), hana::first(pairs)))
>::value...
>::value,
"hana::make_map(pairs...) requires all the keys to be "
"Comparable at compile-time");
//! @todo
//! This can be implemented more efficiently by doing the check
//! inside each bucket instead.
static_assert(!detail::has_duplicates::value,
"hana::make_map({keys, values}...) requires all the keys to be unique");
static_assert(!detail::has_duplicates::value,
"hana::make_map({keys, values}...) requires all the keys to have different hashes");
#endif
using Map = typename detail::make_map_type::type...>::type;
return Map{hana::make_basic_tuple(static_cast(pairs)...)};
}
};
//////////////////////////////////////////////////////////////////////////
// keys
//////////////////////////////////////////////////////////////////////////
template <>
struct keys_impl {
template
static constexpr decltype(auto) apply(Map&& map) {
return hana::transform(static_cast