add deduction guides #15

This commit is contained in:
BlackMATov
2020-11-30 01:53:54 +07:00
parent 7d87cd34d3
commit cdae59eb5b
11 changed files with 781 additions and 6 deletions

View File

@@ -0,0 +1,24 @@
/*******************************************************************************
* This file is part of the "https://github.com/blackmatov/flat.hpp"
* For conditions of distribution and use, see copyright notice in LICENSE.md
* Copyright (C) 2019-2020, by Matvey Cherevko (blackmatov@gmail.com)
******************************************************************************/
#pragma once
#include <type_traits>
#include <utility>
namespace flat_hpp::detail
{
template < typename Allocator, typename = void >
struct is_allocator : std::false_type {};
template < typename Allocator >
struct is_allocator<Allocator, std::void_t<
typename Allocator::value_type,
decltype(std::declval<Allocator&>().deallocate(
std::declval<Allocator&>().allocate(std::size_t{1}),
std::size_t{1}))
>> : std::true_type {};
}

View File

@@ -0,0 +1,22 @@
/*******************************************************************************
* This file is part of the "https://github.com/blackmatov/flat.hpp"
* For conditions of distribution and use, see copyright notice in LICENSE.md
* Copyright (C) 2019-2020, by Matvey Cherevko (blackmatov@gmail.com)
******************************************************************************/
#pragma once
#include <iterator>
#include <type_traits>
namespace flat_hpp::detail
{
template < typename InputIter >
using iter_value_type = typename std::iterator_traits<InputIter>::value_type;
template < typename InputIter >
using iter_key_type = std::remove_const_t<typename iter_value_type<InputIter>::first_type>;
template < typename InputIter >
using iter_mapped_type = typename iter_value_type<InputIter>::second_type;
}

View File

@@ -6,18 +6,21 @@
#pragma once
#include <vector>
#include <cassert>
#include <utility>
#include <algorithm>
#include <cassert>
#include <functional>
#include <type_traits>
#include <initializer_list>
#include <stdexcept>
#include <type_traits>
#include <utility>
#include <vector>
#include "detail/is_sorted.hpp"
#include "detail/eq_compare.hpp"
#include "detail/pair_compare.hpp"
#include "detail/is_allocator.hpp"
#include "detail/is_sorted.hpp"
#include "detail/is_transparent.hpp"
#include "detail/iter_traits.hpp"
#include "detail/pair_compare.hpp"
namespace flat_hpp
{

View File

@@ -709,6 +709,102 @@ namespace flat_hpp
};
}
namespace flat_hpp
{
template < typename InputIter, typename Allocator
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_map(InputIter, InputIter, Allocator, int* msvc_2017_workaround = nullptr)
-> flat_map<detail::iter_key_type<InputIter>, detail::iter_mapped_type<InputIter>>;
template < typename InputIter, typename Allocator
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_map(sorted_range_t, InputIter, InputIter, Allocator, int* msvc_2017_workaround = nullptr)
-> flat_map<detail::iter_key_type<InputIter>, detail::iter_mapped_type<InputIter>>;
template < typename InputIter, typename Allocator
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_map(sorted_unique_range_t, InputIter, InputIter, Allocator, int* msvc_2017_workaround = nullptr)
-> flat_map<detail::iter_key_type<InputIter>, detail::iter_mapped_type<InputIter>>;
//
template < typename InputIter
, typename Compare = std::less<detail::iter_key_type<InputIter>>
, typename Allocator = std::allocator<std::pair<
std::add_const_t<detail::iter_key_type<InputIter>>,
detail::iter_mapped_type<InputIter>>>
, std::enable_if_t<!detail::is_allocator<Compare>::value, int> = 0
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_map(InputIter, InputIter, Compare = Compare(), Allocator = Allocator())
-> flat_map<detail::iter_key_type<InputIter>, detail::iter_mapped_type<InputIter>, Compare>;
template < typename InputIter
, typename Compare = std::less<detail::iter_key_type<InputIter>>
, typename Allocator = std::allocator<std::pair<
std::add_const_t<detail::iter_key_type<InputIter>>,
detail::iter_mapped_type<InputIter>>>
, std::enable_if_t<!detail::is_allocator<Compare>::value, int> = 0
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_map(sorted_range_t, InputIter, InputIter, Compare = Compare(), Allocator = Allocator())
-> flat_map<detail::iter_key_type<InputIter>, detail::iter_mapped_type<InputIter>, Compare>;
template < typename InputIter
, typename Compare = std::less<detail::iter_key_type<InputIter>>
, typename Allocator = std::allocator<std::pair<
std::add_const_t<detail::iter_key_type<InputIter>>,
detail::iter_mapped_type<InputIter>>>
, std::enable_if_t<!detail::is_allocator<Compare>::value, int> = 0
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_map(sorted_unique_range_t, InputIter, InputIter, Compare = Compare(), Allocator = Allocator())
-> flat_map<detail::iter_key_type<InputIter>, detail::iter_mapped_type<InputIter>, Compare>;
//
template < typename Key, typename Value
, typename Allocator = std::allocator<std::pair<const Key, Value>>
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_map(std::initializer_list<std::pair<Key, Value>>, Allocator, int* msvc_2017_workaround = nullptr)
-> flat_map<std::remove_const_t<Key>, Value>;
template < typename Key, typename Value
, typename Allocator = std::allocator<std::pair<const Key, Value>>
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_map(sorted_range_t, std::initializer_list<std::pair<Key, Value>>, Allocator, int* msvc_2017_workaround = nullptr)
-> flat_map<std::remove_const_t<Key>, Value>;
template < typename Key, typename Value
, typename Allocator = std::allocator<std::pair<const Key, Value>>
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_map(sorted_unique_range_t, std::initializer_list<std::pair<Key, Value>>, Allocator, int* msvc_2017_workaround = nullptr)
-> flat_map<std::remove_const_t<Key>, Value>;
//
template < typename Key, typename Value
, typename Compare = std::less<std::remove_const_t<Key>>
, typename Allocator = std::allocator<std::pair<const Key, Value>>
, std::enable_if_t<!detail::is_allocator<Compare>::value, int> = 0
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_map(std::initializer_list<std::pair<Key, Value>>, Compare = Compare(), Allocator = Allocator())
-> flat_map<std::remove_const_t<Key>, Value, Compare>;
template < typename Key, typename Value
, typename Compare = std::less<std::remove_const_t<Key>>
, typename Allocator = std::allocator<std::pair<const Key, Value>>
, std::enable_if_t<!detail::is_allocator<Compare>::value, int> = 0
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_map(sorted_range_t, std::initializer_list<std::pair<Key, Value>>, Compare = Compare(), Allocator = Allocator())
-> flat_map<std::remove_const_t<Key>, Value, Compare>;
template < typename Key, typename Value
, typename Compare = std::less<std::remove_const_t<Key>>
, typename Allocator = std::allocator<std::pair<const Key, Value>>
, std::enable_if_t<!detail::is_allocator<Compare>::value, int> = 0
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_map(sorted_unique_range_t, std::initializer_list<std::pair<Key, Value>>, Compare = Compare(), Allocator = Allocator())
-> flat_map<std::remove_const_t<Key>, Value, Compare>;
}
namespace flat_hpp
{
template < typename Key

View File

@@ -594,6 +594,102 @@ namespace flat_hpp
};
}
namespace flat_hpp
{
template < typename InputIter, typename Allocator
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_multimap(InputIter, InputIter, Allocator, int* msvc_2017_workaround = nullptr)
-> flat_multimap<detail::iter_key_type<InputIter>, detail::iter_mapped_type<InputIter>>;
template < typename InputIter, typename Allocator
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_multimap(sorted_range_t, InputIter, InputIter, Allocator, int* msvc_2017_workaround = nullptr)
-> flat_multimap<detail::iter_key_type<InputIter>, detail::iter_mapped_type<InputIter>>;
template < typename InputIter, typename Allocator
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_multimap(sorted_unique_range_t, InputIter, InputIter, Allocator, int* msvc_2017_workaround = nullptr)
-> flat_multimap<detail::iter_key_type<InputIter>, detail::iter_mapped_type<InputIter>>;
//
template < typename InputIter
, typename Compare = std::less<detail::iter_key_type<InputIter>>
, typename Allocator = std::allocator<std::pair<
std::add_const_t<detail::iter_key_type<InputIter>>,
detail::iter_mapped_type<InputIter>>>
, std::enable_if_t<!detail::is_allocator<Compare>::value, int> = 0
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_multimap(InputIter, InputIter, Compare = Compare(), Allocator = Allocator())
-> flat_multimap<detail::iter_key_type<InputIter>, detail::iter_mapped_type<InputIter>, Compare>;
template < typename InputIter
, typename Compare = std::less<detail::iter_key_type<InputIter>>
, typename Allocator = std::allocator<std::pair<
std::add_const_t<detail::iter_key_type<InputIter>>,
detail::iter_mapped_type<InputIter>>>
, std::enable_if_t<!detail::is_allocator<Compare>::value, int> = 0
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_multimap(sorted_range_t, InputIter, InputIter, Compare = Compare(), Allocator = Allocator())
-> flat_multimap<detail::iter_key_type<InputIter>, detail::iter_mapped_type<InputIter>, Compare>;
template < typename InputIter
, typename Compare = std::less<detail::iter_key_type<InputIter>>
, typename Allocator = std::allocator<std::pair<
std::add_const_t<detail::iter_key_type<InputIter>>,
detail::iter_mapped_type<InputIter>>>
, std::enable_if_t<!detail::is_allocator<Compare>::value, int> = 0
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_multimap(sorted_unique_range_t, InputIter, InputIter, Compare = Compare(), Allocator = Allocator())
-> flat_multimap<detail::iter_key_type<InputIter>, detail::iter_mapped_type<InputIter>, Compare>;
//
template < typename Key, typename Value
, typename Allocator = std::allocator<std::pair<const Key, Value>>
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_multimap(std::initializer_list<std::pair<Key, Value>>, Allocator, int* msvc_2017_workaround = nullptr)
-> flat_multimap<std::remove_const_t<Key>, Value>;
template < typename Key, typename Value
, typename Allocator = std::allocator<std::pair<const Key, Value>>
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_multimap(sorted_range_t, std::initializer_list<std::pair<Key, Value>>, Allocator, int* msvc_2017_workaround = nullptr)
-> flat_multimap<std::remove_const_t<Key>, Value>;
template < typename Key, typename Value
, typename Allocator = std::allocator<std::pair<const Key, Value>>
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_multimap(sorted_unique_range_t, std::initializer_list<std::pair<Key, Value>>, Allocator, int* msvc_2017_workaround = nullptr)
-> flat_multimap<std::remove_const_t<Key>, Value>;
//
template < typename Key, typename Value
, typename Compare = std::less<std::remove_const_t<Key>>
, typename Allocator = std::allocator<std::pair<const Key, Value>>
, std::enable_if_t<!detail::is_allocator<Compare>::value, int> = 0
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_multimap(std::initializer_list<std::pair<Key, Value>>, Compare = Compare(), Allocator = Allocator())
-> flat_multimap<std::remove_const_t<Key>, Value, Compare>;
template < typename Key, typename Value
, typename Compare = std::less<std::remove_const_t<Key>>
, typename Allocator = std::allocator<std::pair<const Key, Value>>
, std::enable_if_t<!detail::is_allocator<Compare>::value, int> = 0
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_multimap(sorted_range_t, std::initializer_list<std::pair<Key, Value>>, Compare = Compare(), Allocator = Allocator())
-> flat_multimap<std::remove_const_t<Key>, Value, Compare>;
template < typename Key, typename Value
, typename Compare = std::less<std::remove_const_t<Key>>
, typename Allocator = std::allocator<std::pair<const Key, Value>>
, std::enable_if_t<!detail::is_allocator<Compare>::value, int> = 0
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_multimap(sorted_unique_range_t, std::initializer_list<std::pair<Key, Value>>, Compare = Compare(), Allocator = Allocator())
-> flat_multimap<std::remove_const_t<Key>, Value, Compare>;
}
namespace flat_hpp
{
template < typename Key

View File

@@ -510,6 +510,96 @@ namespace flat_hpp
};
}
namespace flat_hpp
{
template < typename InputIter, typename Allocator
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_multiset(InputIter, InputIter, Allocator, int* msvc_2017_workaround = nullptr)
-> flat_multiset<detail::iter_value_type<InputIter>>;
template < typename InputIter, typename Allocator
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_multiset(sorted_range_t, InputIter, InputIter, Allocator, int* msvc_2017_workaround = nullptr)
-> flat_multiset<detail::iter_value_type<InputIter>>;
template < typename InputIter, typename Allocator
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_multiset(sorted_unique_range_t, InputIter, InputIter, Allocator, int* msvc_2017_workaround = nullptr)
-> flat_multiset<detail::iter_value_type<InputIter>>;
//
template < typename InputIter
, typename Compare = std::less<detail::iter_value_type<InputIter>>
, typename Allocator = std::allocator<detail::iter_value_type<InputIter>>
, std::enable_if_t<!detail::is_allocator<Compare>::value, int> = 0
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_multiset(InputIter, InputIter, Compare = Compare(), Allocator = Allocator())
-> flat_multiset<detail::iter_value_type<InputIter>, Compare>;
template < typename InputIter
, typename Compare = std::less<detail::iter_value_type<InputIter>>
, typename Allocator = std::allocator<detail::iter_value_type<InputIter>>
, std::enable_if_t<!detail::is_allocator<Compare>::value, int> = 0
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_multiset(sorted_range_t, InputIter, InputIter, Compare = Compare(), Allocator = Allocator())
-> flat_multiset<detail::iter_value_type<InputIter>, Compare>;
template < typename InputIter
, typename Compare = std::less<detail::iter_value_type<InputIter>>
, typename Allocator = std::allocator<detail::iter_value_type<InputIter>>
, std::enable_if_t<!detail::is_allocator<Compare>::value, int> = 0
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_multiset(sorted_unique_range_t, InputIter, InputIter, Compare = Compare(), Allocator = Allocator())
-> flat_multiset<detail::iter_value_type<InputIter>, Compare>;
//
template < typename Key
, typename Allocator = std::allocator<Key>
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_multiset(std::initializer_list<Key>, Allocator, int* msvc_2017_workaround = nullptr)
-> flat_multiset<Key>;
template < typename Key
, typename Allocator = std::allocator<Key>
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_multiset(sorted_range_t, std::initializer_list<Key>, Allocator, int* msvc_2017_workaround = nullptr)
-> flat_multiset<Key>;
template < typename Key
, typename Allocator = std::allocator<Key>
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_multiset(sorted_unique_range_t, std::initializer_list<Key>, Allocator, int* msvc_2017_workaround = nullptr)
-> flat_multiset<Key>;
//
template < typename Key
, typename Compare = std::less<Key>
, typename Allocator = std::allocator<Key>
, std::enable_if_t<!detail::is_allocator<Compare>::value, int> = 0
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_multiset(std::initializer_list<Key>, Compare = Compare(), Allocator = Allocator())
-> flat_multiset<Key, Compare>;
template < typename Key
, typename Compare = std::less<Key>
, typename Allocator = std::allocator<Key>
, std::enable_if_t<!detail::is_allocator<Compare>::value, int> = 0
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_multiset(sorted_range_t, std::initializer_list<Key>, Compare = Compare(), Allocator = Allocator())
-> flat_multiset<Key, Compare>;
template < typename Key
, typename Compare = std::less<Key>
, typename Allocator = std::allocator<Key>
, std::enable_if_t<!detail::is_allocator<Compare>::value, int> = 0
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_multiset(sorted_unique_range_t, std::initializer_list<Key>, Compare = Compare(), Allocator = Allocator())
-> flat_multiset<Key, Compare>;
}
namespace flat_hpp
{
template < typename Key

View File

@@ -583,6 +583,96 @@ namespace flat_hpp
};
}
namespace flat_hpp
{
template < typename InputIter, typename Allocator
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_set(InputIter, InputIter, Allocator, int* msvc_2017_workaround = nullptr)
-> flat_set<detail::iter_value_type<InputIter>>;
template < typename InputIter, typename Allocator
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_set(sorted_range_t, InputIter, InputIter, Allocator, int* msvc_2017_workaround = nullptr)
-> flat_set<detail::iter_value_type<InputIter>>;
template < typename InputIter, typename Allocator
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_set(sorted_unique_range_t, InputIter, InputIter, Allocator, int* msvc_2017_workaround = nullptr)
-> flat_set<detail::iter_value_type<InputIter>>;
//
template < typename InputIter
, typename Compare = std::less<detail::iter_value_type<InputIter>>
, typename Allocator = std::allocator<detail::iter_value_type<InputIter>>
, std::enable_if_t<!detail::is_allocator<Compare>::value, int> = 0
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_set(InputIter, InputIter, Compare = Compare(), Allocator = Allocator())
-> flat_set<detail::iter_value_type<InputIter>, Compare>;
template < typename InputIter
, typename Compare = std::less<detail::iter_value_type<InputIter>>
, typename Allocator = std::allocator<detail::iter_value_type<InputIter>>
, std::enable_if_t<!detail::is_allocator<Compare>::value, int> = 0
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_set(sorted_range_t, InputIter, InputIter, Compare = Compare(), Allocator = Allocator())
-> flat_set<detail::iter_value_type<InputIter>, Compare>;
template < typename InputIter
, typename Compare = std::less<detail::iter_value_type<InputIter>>
, typename Allocator = std::allocator<detail::iter_value_type<InputIter>>
, std::enable_if_t<!detail::is_allocator<Compare>::value, int> = 0
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_set(sorted_unique_range_t, InputIter, InputIter, Compare = Compare(), Allocator = Allocator())
-> flat_set<detail::iter_value_type<InputIter>, Compare>;
//
template < typename Key
, typename Allocator = std::allocator<Key>
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_set(std::initializer_list<Key>, Allocator, int* msvc_2017_workaround = nullptr)
-> flat_set<Key>;
template < typename Key
, typename Allocator = std::allocator<Key>
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_set(sorted_range_t, std::initializer_list<Key>, Allocator, int* msvc_2017_workaround = nullptr)
-> flat_set<Key>;
template < typename Key
, typename Allocator = std::allocator<Key>
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_set(sorted_unique_range_t, std::initializer_list<Key>, Allocator, int* msvc_2017_workaround = nullptr)
-> flat_set<Key>;
//
template < typename Key
, typename Compare = std::less<Key>
, typename Allocator = std::allocator<Key>
, std::enable_if_t<!detail::is_allocator<Compare>::value, int> = 0
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_set(std::initializer_list<Key>, Compare = Compare(), Allocator = Allocator())
-> flat_set<Key, Compare>;
template < typename Key
, typename Compare = std::less<Key>
, typename Allocator = std::allocator<Key>
, std::enable_if_t<!detail::is_allocator<Compare>::value, int> = 0
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_set(sorted_range_t, std::initializer_list<Key>, Compare = Compare(), Allocator = Allocator())
-> flat_set<Key, Compare>;
template < typename Key
, typename Compare = std::less<Key>
, typename Allocator = std::allocator<Key>
, std::enable_if_t<!detail::is_allocator<Compare>::value, int> = 0
, std::enable_if_t<detail::is_allocator<Allocator>::value, int> = 0 >
flat_set(sorted_unique_range_t, std::initializer_list<Key>, Compare = Compare(), Allocator = Allocator())
-> flat_set<Key, Compare>;
}
namespace flat_hpp
{
template < typename Key

View File

@@ -57,6 +57,109 @@ namespace
}
TEST_CASE("flat_map") {
SUBCASE("guides") {
{
std::vector<std::pair<int,unsigned>> vs;
auto s0 = flat_map(vs.begin(), vs.end());
auto s1 = flat_map(flat_hpp::sorted_range, vs.begin(), vs.end());
auto s2 = flat_map(flat_hpp::sorted_unique_range, vs.begin(), vs.end());
auto s3 = flat_map(vs.begin(), vs.end(), std::less<int>());
auto s4 = flat_map(flat_hpp::sorted_range, vs.begin(), vs.end(), std::less<int>());
auto s5 = flat_map(flat_hpp::sorted_unique_range, vs.begin(), vs.end(), std::less<int>());
auto s6 = flat_map(vs.begin(), vs.end(), std::allocator<int>());
auto s7 = flat_map(flat_hpp::sorted_range, vs.begin(), vs.end(), std::allocator<int>());
auto s8 = flat_map(flat_hpp::sorted_unique_range, vs.begin(), vs.end(), std::allocator<int>());
auto s9 = flat_map(vs.begin(), vs.end(), std::less<int>(), std::allocator<int>());
auto s10 = flat_map(flat_hpp::sorted_range, vs.begin(), vs.end(), std::less<int>(), std::allocator<int>());
auto s11 = flat_map(flat_hpp::sorted_unique_range, vs.begin(), vs.end(), std::less<int>(), std::allocator<int>());
STATIC_REQUIRE(std::is_same_v<decltype(s0)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s1)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s2)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s3)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s4)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s5)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s6)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s7)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s8)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s9)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s10)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s11)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s0)::mapped_type, unsigned>);
STATIC_REQUIRE(std::is_same_v<decltype(s1)::mapped_type, unsigned>);
STATIC_REQUIRE(std::is_same_v<decltype(s2)::mapped_type, unsigned>);
STATIC_REQUIRE(std::is_same_v<decltype(s3)::mapped_type, unsigned>);
STATIC_REQUIRE(std::is_same_v<decltype(s4)::mapped_type, unsigned>);
STATIC_REQUIRE(std::is_same_v<decltype(s5)::mapped_type, unsigned>);
STATIC_REQUIRE(std::is_same_v<decltype(s6)::mapped_type, unsigned>);
STATIC_REQUIRE(std::is_same_v<decltype(s7)::mapped_type, unsigned>);
STATIC_REQUIRE(std::is_same_v<decltype(s8)::mapped_type, unsigned>);
STATIC_REQUIRE(std::is_same_v<decltype(s9)::mapped_type, unsigned>);
STATIC_REQUIRE(std::is_same_v<decltype(s10)::mapped_type, unsigned>);
STATIC_REQUIRE(std::is_same_v<decltype(s11)::mapped_type, unsigned>);
}
{
auto s1 = flat_map({std::pair{1,1u}, std::pair{2,2u}});
auto s2 = flat_map(flat_hpp::sorted_range, {std::pair{1,1u}, std::pair{2,2u}});
auto s3 = flat_map(flat_hpp::sorted_unique_range, {std::pair{1,1u}, std::pair{2,2u}});
STATIC_REQUIRE(std::is_same_v<decltype(s1)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s2)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s3)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s1)::mapped_type, unsigned>);
STATIC_REQUIRE(std::is_same_v<decltype(s2)::mapped_type, unsigned>);
STATIC_REQUIRE(std::is_same_v<decltype(s3)::mapped_type, unsigned>);
}
{
auto s1 = flat_map({std::pair{1,1u}, std::pair{2,2u}}, std::less<int>());
auto s2 = flat_map(flat_hpp::sorted_range, {std::pair{1,1u}, std::pair{2,2u}}, std::less<int>());
auto s3 = flat_map(flat_hpp::sorted_unique_range, {std::pair{1,1u}, std::pair{2,2u}}, std::less<int>());
STATIC_REQUIRE(std::is_same_v<decltype(s1)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s2)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s3)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s1)::mapped_type, unsigned>);
STATIC_REQUIRE(std::is_same_v<decltype(s2)::mapped_type, unsigned>);
STATIC_REQUIRE(std::is_same_v<decltype(s3)::mapped_type, unsigned>);
}
{
auto s1 = flat_map({std::pair{1,1u}, std::pair{2,2u}}, std::allocator<int>());
auto s2 = flat_map(flat_hpp::sorted_range, {std::pair{1,1u}, std::pair{2,2u}}, std::allocator<int>());
auto s3 = flat_map(flat_hpp::sorted_unique_range, {std::pair{1,1u}, std::pair{2,2u}}, std::allocator<int>());
STATIC_REQUIRE(std::is_same_v<decltype(s1)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s2)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s3)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s1)::mapped_type, unsigned>);
STATIC_REQUIRE(std::is_same_v<decltype(s2)::mapped_type, unsigned>);
STATIC_REQUIRE(std::is_same_v<decltype(s3)::mapped_type, unsigned>);
}
{
auto s1 = flat_map({std::pair{1,1u}, std::pair{2,2u}}, std::less<int>(), std::allocator<int>());
auto s2 = flat_map(flat_hpp::sorted_range, {std::pair{1,1u}, std::pair{2,2u}}, std::less<int>(), std::allocator<int>());
auto s3 = flat_map(flat_hpp::sorted_unique_range, {std::pair{1,1u}, std::pair{2,2u}}, std::less<int>(), std::allocator<int>());
STATIC_REQUIRE(std::is_same_v<decltype(s1)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s2)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s3)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s1)::mapped_type, unsigned>);
STATIC_REQUIRE(std::is_same_v<decltype(s2)::mapped_type, unsigned>);
STATIC_REQUIRE(std::is_same_v<decltype(s3)::mapped_type, unsigned>);
}
}
SUBCASE("detail") {
STATIC_REQUIRE(detail::is_transparent<std::less<>, int>::value);
STATIC_REQUIRE_FALSE(detail::is_transparent<std::less<int>, int>::value);

View File

@@ -57,6 +57,109 @@ namespace
}
TEST_CASE("flat_multimap") {
SUBCASE("guides") {
{
std::vector<std::pair<int,unsigned>> vs;
auto s0 = flat_multimap(vs.begin(), vs.end());
auto s1 = flat_multimap(flat_hpp::sorted_range, vs.begin(), vs.end());
auto s2 = flat_multimap(flat_hpp::sorted_unique_range, vs.begin(), vs.end());
auto s3 = flat_multimap(vs.begin(), vs.end(), std::less<int>());
auto s4 = flat_multimap(flat_hpp::sorted_range, vs.begin(), vs.end(), std::less<int>());
auto s5 = flat_multimap(flat_hpp::sorted_unique_range, vs.begin(), vs.end(), std::less<int>());
auto s6 = flat_multimap(vs.begin(), vs.end(), std::allocator<int>());
auto s7 = flat_multimap(flat_hpp::sorted_range, vs.begin(), vs.end(), std::allocator<int>());
auto s8 = flat_multimap(flat_hpp::sorted_unique_range, vs.begin(), vs.end(), std::allocator<int>());
auto s9 = flat_multimap(vs.begin(), vs.end(), std::less<int>(), std::allocator<int>());
auto s10 = flat_multimap(flat_hpp::sorted_range, vs.begin(), vs.end(), std::less<int>(), std::allocator<int>());
auto s11 = flat_multimap(flat_hpp::sorted_unique_range, vs.begin(), vs.end(), std::less<int>(), std::allocator<int>());
STATIC_REQUIRE(std::is_same_v<decltype(s0)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s1)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s2)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s3)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s4)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s5)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s6)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s7)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s8)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s9)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s10)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s11)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s0)::mapped_type, unsigned>);
STATIC_REQUIRE(std::is_same_v<decltype(s1)::mapped_type, unsigned>);
STATIC_REQUIRE(std::is_same_v<decltype(s2)::mapped_type, unsigned>);
STATIC_REQUIRE(std::is_same_v<decltype(s3)::mapped_type, unsigned>);
STATIC_REQUIRE(std::is_same_v<decltype(s4)::mapped_type, unsigned>);
STATIC_REQUIRE(std::is_same_v<decltype(s5)::mapped_type, unsigned>);
STATIC_REQUIRE(std::is_same_v<decltype(s6)::mapped_type, unsigned>);
STATIC_REQUIRE(std::is_same_v<decltype(s7)::mapped_type, unsigned>);
STATIC_REQUIRE(std::is_same_v<decltype(s8)::mapped_type, unsigned>);
STATIC_REQUIRE(std::is_same_v<decltype(s9)::mapped_type, unsigned>);
STATIC_REQUIRE(std::is_same_v<decltype(s10)::mapped_type, unsigned>);
STATIC_REQUIRE(std::is_same_v<decltype(s11)::mapped_type, unsigned>);
}
{
auto s1 = flat_multimap({std::pair{1,1u}, std::pair{2,2u}});
auto s2 = flat_multimap(flat_hpp::sorted_range, {std::pair{1,1u}, std::pair{2,2u}});
auto s3 = flat_multimap(flat_hpp::sorted_unique_range, {std::pair{1,1u}, std::pair{2,2u}});
STATIC_REQUIRE(std::is_same_v<decltype(s1)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s2)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s3)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s1)::mapped_type, unsigned>);
STATIC_REQUIRE(std::is_same_v<decltype(s2)::mapped_type, unsigned>);
STATIC_REQUIRE(std::is_same_v<decltype(s3)::mapped_type, unsigned>);
}
{
auto s1 = flat_multimap({std::pair{1,1u}, std::pair{2,2u}}, std::less<int>());
auto s2 = flat_multimap(flat_hpp::sorted_range, {std::pair{1,1u}, std::pair{2,2u}}, std::less<int>());
auto s3 = flat_multimap(flat_hpp::sorted_unique_range, {std::pair{1,1u}, std::pair{2,2u}}, std::less<int>());
STATIC_REQUIRE(std::is_same_v<decltype(s1)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s2)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s3)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s1)::mapped_type, unsigned>);
STATIC_REQUIRE(std::is_same_v<decltype(s2)::mapped_type, unsigned>);
STATIC_REQUIRE(std::is_same_v<decltype(s3)::mapped_type, unsigned>);
}
{
auto s1 = flat_multimap({std::pair{1,1u}, std::pair{2,2u}}, std::allocator<int>());
auto s2 = flat_multimap(flat_hpp::sorted_range, {std::pair{1,1u}, std::pair{2,2u}}, std::allocator<int>());
auto s3 = flat_multimap(flat_hpp::sorted_unique_range, {std::pair{1,1u}, std::pair{2,2u}}, std::allocator<int>());
STATIC_REQUIRE(std::is_same_v<decltype(s1)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s2)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s3)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s1)::mapped_type, unsigned>);
STATIC_REQUIRE(std::is_same_v<decltype(s2)::mapped_type, unsigned>);
STATIC_REQUIRE(std::is_same_v<decltype(s3)::mapped_type, unsigned>);
}
{
auto s1 = flat_multimap({std::pair{1,1u}, std::pair{2,2u}}, std::less<int>(), std::allocator<int>());
auto s2 = flat_multimap(flat_hpp::sorted_range, {std::pair{1,1u}, std::pair{2,2u}}, std::less<int>(), std::allocator<int>());
auto s3 = flat_multimap(flat_hpp::sorted_unique_range, {std::pair{1,1u}, std::pair{2,2u}}, std::less<int>(), std::allocator<int>());
STATIC_REQUIRE(std::is_same_v<decltype(s1)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s2)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s3)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s1)::mapped_type, unsigned>);
STATIC_REQUIRE(std::is_same_v<decltype(s2)::mapped_type, unsigned>);
STATIC_REQUIRE(std::is_same_v<decltype(s3)::mapped_type, unsigned>);
}
}
SUBCASE("detail") {
STATIC_REQUIRE(detail::is_transparent<std::less<>, int>::value);
STATIC_REQUIRE_FALSE(detail::is_transparent<std::less<int>, int>::value);

View File

@@ -57,6 +57,80 @@ namespace
}
TEST_CASE("flat_multiset") {
SUBCASE("guides") {
{
std::vector<int> vs;
auto s0 = flat_multiset(vs.begin(), vs.end());
auto s1 = flat_multiset(flat_hpp::sorted_range, vs.begin(), vs.end());
auto s2 = flat_multiset(flat_hpp::sorted_unique_range, vs.begin(), vs.end());
auto s3 = flat_multiset(vs.begin(), vs.end(), std::less<int>());
auto s4 = flat_multiset(flat_hpp::sorted_range, vs.begin(), vs.end(), std::less<int>());
auto s5 = flat_multiset(flat_hpp::sorted_unique_range, vs.begin(), vs.end(), std::less<int>());
auto s6 = flat_multiset(vs.begin(), vs.end(), std::allocator<int>());
auto s7 = flat_multiset(flat_hpp::sorted_range, vs.begin(), vs.end(), std::allocator<int>());
auto s8 = flat_multiset(flat_hpp::sorted_unique_range, vs.begin(), vs.end(), std::allocator<int>());
auto s9 = flat_multiset(vs.begin(), vs.end(), std::less<int>(), std::allocator<int>());
auto s10 = flat_multiset(flat_hpp::sorted_range, vs.begin(), vs.end(), std::less<int>(), std::allocator<int>());
auto s11 = flat_multiset(flat_hpp::sorted_unique_range, vs.begin(), vs.end(), std::less<int>(), std::allocator<int>());
STATIC_REQUIRE(std::is_same_v<decltype(s0)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s1)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s2)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s3)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s4)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s5)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s6)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s7)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s8)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s9)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s10)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s11)::key_type, int>);
}
{
auto s1 = flat_multiset({1, 2});
auto s2 = flat_multiset(flat_hpp::sorted_range, {1, 2});
auto s3 = flat_multiset(flat_hpp::sorted_unique_range, {1, 2});
STATIC_REQUIRE(std::is_same_v<decltype(s1)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s2)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s3)::key_type, int>);
}
{
auto s1 = flat_multiset({1, 2}, std::less<int>());
auto s2 = flat_multiset(flat_hpp::sorted_range, {1, 2}, std::less<int>());
auto s3 = flat_multiset(flat_hpp::sorted_unique_range, {1, 2}, std::less<int>());
STATIC_REQUIRE(std::is_same_v<decltype(s1)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s2)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s3)::key_type, int>);
}
{
auto s1 = flat_multiset({1, 2}, std::allocator<int>());
auto s2 = flat_multiset(flat_hpp::sorted_range, {1, 2}, std::allocator<int>());
auto s3 = flat_multiset(flat_hpp::sorted_unique_range, {1, 2}, std::allocator<int>());
STATIC_REQUIRE(std::is_same_v<decltype(s1)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s2)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s3)::key_type, int>);
}
{
auto s1 = flat_multiset({1, 2}, std::less<int>(), std::allocator<int>());
auto s2 = flat_multiset(flat_hpp::sorted_range, {1, 2}, std::less<int>(), std::allocator<int>());
auto s3 = flat_multiset(flat_hpp::sorted_unique_range, {1, 2}, std::less<int>(), std::allocator<int>());
STATIC_REQUIRE(std::is_same_v<decltype(s1)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s2)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s3)::key_type, int>);
}
}
SUBCASE("detail") {
STATIC_REQUIRE(detail::is_transparent<std::less<>, int>::value);
STATIC_REQUIRE_FALSE(detail::is_transparent<std::less<int>, int>::value);

View File

@@ -57,6 +57,80 @@ namespace
}
TEST_CASE("flat_set") {
SUBCASE("guides") {
{
std::vector<int> vs;
auto s0 = flat_set(vs.begin(), vs.end());
auto s1 = flat_set(flat_hpp::sorted_range, vs.begin(), vs.end());
auto s2 = flat_set(flat_hpp::sorted_unique_range, vs.begin(), vs.end());
auto s3 = flat_set(vs.begin(), vs.end(), std::less<int>());
auto s4 = flat_set(flat_hpp::sorted_range, vs.begin(), vs.end(), std::less<int>());
auto s5 = flat_set(flat_hpp::sorted_unique_range, vs.begin(), vs.end(), std::less<int>());
auto s6 = flat_set(vs.begin(), vs.end(), std::allocator<int>());
auto s7 = flat_set(flat_hpp::sorted_range, vs.begin(), vs.end(), std::allocator<int>());
auto s8 = flat_set(flat_hpp::sorted_unique_range, vs.begin(), vs.end(), std::allocator<int>());
auto s9 = flat_set(vs.begin(), vs.end(), std::less<int>(), std::allocator<int>());
auto s10 = flat_set(flat_hpp::sorted_range, vs.begin(), vs.end(), std::less<int>(), std::allocator<int>());
auto s11 = flat_set(flat_hpp::sorted_unique_range, vs.begin(), vs.end(), std::less<int>(), std::allocator<int>());
STATIC_REQUIRE(std::is_same_v<decltype(s0)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s1)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s2)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s3)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s4)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s5)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s6)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s7)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s8)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s9)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s10)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s11)::key_type, int>);
}
{
auto s1 = flat_set({1, 2});
auto s2 = flat_set(flat_hpp::sorted_range, {1, 2});
auto s3 = flat_set(flat_hpp::sorted_unique_range, {1, 2});
STATIC_REQUIRE(std::is_same_v<decltype(s1)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s2)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s3)::key_type, int>);
}
{
auto s1 = flat_set({1, 2}, std::less<int>());
auto s2 = flat_set(flat_hpp::sorted_range, {1, 2}, std::less<int>());
auto s3 = flat_set(flat_hpp::sorted_unique_range, {1, 2}, std::less<int>());
STATIC_REQUIRE(std::is_same_v<decltype(s1)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s2)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s3)::key_type, int>);
}
{
auto s1 = flat_set({1, 2}, std::allocator<int>());
auto s2 = flat_set(flat_hpp::sorted_range, {1, 2}, std::allocator<int>());
auto s3 = flat_set(flat_hpp::sorted_unique_range, {1, 2}, std::allocator<int>());
STATIC_REQUIRE(std::is_same_v<decltype(s1)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s2)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s3)::key_type, int>);
}
{
auto s1 = flat_set({1, 2}, std::less<int>(), std::allocator<int>());
auto s2 = flat_set(flat_hpp::sorted_range, {1, 2}, std::less<int>(), std::allocator<int>());
auto s3 = flat_set(flat_hpp::sorted_unique_range, {1, 2}, std::less<int>(), std::allocator<int>());
STATIC_REQUIRE(std::is_same_v<decltype(s1)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s2)::key_type, int>);
STATIC_REQUIRE(std::is_same_v<decltype(s3)::key_type, int>);
}
}
SUBCASE("detail") {
STATIC_REQUIRE(detail::is_transparent<std::less<>, int>::value);
STATIC_REQUIRE_FALSE(detail::is_transparent<std::less<int>, int>::value);