mirror of
https://github.com/BlackMATov/meta.hpp.git
synced 2025-12-14 03:29:28 +07:00
insert_or_assign for std::sets
This commit is contained in:
@@ -513,6 +513,41 @@ namespace meta_hpp::detail
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace meta_hpp::detail
|
||||||
|
{
|
||||||
|
template < typename Key, typename Compare, typename Allocator >
|
||||||
|
typename std::set<Key, Compare, Allocator>::iterator
|
||||||
|
insert_or_assign(std::set<Key, Compare, Allocator>& set,
|
||||||
|
typename std::set<Key, Compare, Allocator>::value_type&& value)
|
||||||
|
{
|
||||||
|
auto&& [position, inserted] = set.insert(std::move(value));
|
||||||
|
|
||||||
|
if ( inserted ) {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto node = set.extract(position++);
|
||||||
|
node.value() = std::move(value);
|
||||||
|
return set.insert(position, std::move(node));
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename Key, typename Compare, typename Allocator >
|
||||||
|
typename std::set<Key, Compare, Allocator>::iterator
|
||||||
|
insert_or_assign(std::set<Key, Compare, Allocator>& set,
|
||||||
|
const typename std::set<Key, Compare, Allocator>::value_type& value)
|
||||||
|
{
|
||||||
|
auto&& [position, inserted] = set.insert(value);
|
||||||
|
|
||||||
|
if ( inserted ) {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto node = set.extract(position++);
|
||||||
|
node.value() = value;
|
||||||
|
return set.insert(position, std::move(node));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
namespace meta_hpp::detail
|
namespace meta_hpp::detail
|
||||||
{
|
{
|
||||||
template < typename T >
|
template < typename T >
|
||||||
|
|||||||
106
develop/untests/meta_base/insert_or_assign.cpp
Normal file
106
develop/untests/meta_base/insert_or_assign.cpp
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* This file is part of the "https://github.com/blackmatov/meta.hpp"
|
||||||
|
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||||
|
* Copyright (C) 2021-2023, by Matvey Cherevko (blackmatov@gmail.com)
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#include "../meta_untests.hpp"
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
struct movable_value {
|
||||||
|
int key{};
|
||||||
|
int data{};
|
||||||
|
|
||||||
|
movable_value(int k, int d) : key{k}, data{d} {}
|
||||||
|
|
||||||
|
[[maybe_unused]] movable_value(movable_value&&) = default;
|
||||||
|
[[maybe_unused]] movable_value& operator=(movable_value&&) = default;
|
||||||
|
|
||||||
|
movable_value(const movable_value&) = delete;
|
||||||
|
movable_value& operator=(const movable_value&) = delete;
|
||||||
|
|
||||||
|
[[maybe_unused]]
|
||||||
|
friend bool operator<(const movable_value& l, const movable_value& r) noexcept {
|
||||||
|
return l.key < r.key;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[maybe_unused]]
|
||||||
|
friend bool operator==(const movable_value& l, const movable_value& r) noexcept {
|
||||||
|
return l.key == r.key && l.data == r.data;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct copyable_value {
|
||||||
|
int key{};
|
||||||
|
int data{};
|
||||||
|
|
||||||
|
[[maybe_unused]]
|
||||||
|
friend bool operator<(const copyable_value& l, const copyable_value& r) noexcept {
|
||||||
|
return l.key < r.key;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[maybe_unused]]
|
||||||
|
friend bool operator==(const copyable_value& l, const copyable_value& r) noexcept {
|
||||||
|
return l.key == r.key && l.data == r.data;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("meta/meta_base/insert_or_assign") {
|
||||||
|
namespace meta = meta_hpp;
|
||||||
|
using meta::detail::insert_or_assign;
|
||||||
|
|
||||||
|
SUBCASE("movable_value/insert") {
|
||||||
|
std::set<movable_value, std::less<>> s;
|
||||||
|
s.insert({1, 10});
|
||||||
|
s.insert({3, 30});
|
||||||
|
CHECK(*insert_or_assign(s, movable_value{2, 20}) == movable_value{2, 20});
|
||||||
|
{
|
||||||
|
std::set<movable_value, std::less<>> s2;
|
||||||
|
s2.insert({1, 10});
|
||||||
|
s2.insert({2, 20});
|
||||||
|
s2.insert({3, 30});
|
||||||
|
CHECK(s == s2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBCASE("movable_value/replace") {
|
||||||
|
std::set<movable_value, std::less<>> s;
|
||||||
|
s.insert({1, 10});
|
||||||
|
s.insert({3, 30});
|
||||||
|
CHECK(*insert_or_assign(s, movable_value{3, 42}) == movable_value{3, 42});
|
||||||
|
{
|
||||||
|
std::set<movable_value, std::less<>> s2;
|
||||||
|
s2.insert({1, 10});
|
||||||
|
s2.insert({3, 42});
|
||||||
|
CHECK(s == s2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBCASE("copyable_value/insert/0") {
|
||||||
|
std::set<copyable_value, std::less<>> s{{1, 10}, {3, 30}};
|
||||||
|
CHECK(*insert_or_assign(s, copyable_value{2, 20}) == copyable_value{2, 20});
|
||||||
|
CHECK(s == std::set<copyable_value, std::less<>>{{1, 10}, {2, 20}, {3, 30}});
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBCASE("copyable_value/insert/1") {
|
||||||
|
std::set<copyable_value, std::less<>> s{{1, 10}, {3, 30}};
|
||||||
|
copyable_value v{2, 20};
|
||||||
|
CHECK(*insert_or_assign(s, v) == v);
|
||||||
|
CHECK(s == std::set<copyable_value, std::less<>>{{1, 10}, {2, 20}, {3, 30}});
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBCASE("copyable_value/replace/0") {
|
||||||
|
std::set<copyable_value, std::less<>> s{{1, 10}, {3, 30}};
|
||||||
|
CHECK(*insert_or_assign(s, copyable_value{3, 42}) == copyable_value{3, 42});
|
||||||
|
CHECK(s == std::set<copyable_value, std::less<>>{{1, 10}, {3, 42}});
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBCASE("copyable_value/replace/1") {
|
||||||
|
std::set<copyable_value, std::less<>> s{{1, 10}, {3, 30}};
|
||||||
|
copyable_value v{3, 42};
|
||||||
|
CHECK(*insert_or_assign(s, v) == v);
|
||||||
|
CHECK(s == std::set<copyable_value, std::less<>>{{1, 10}, {3, 42}});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,6 +12,7 @@
|
|||||||
#include "meta_base/cvref_traits.hpp"
|
#include "meta_base/cvref_traits.hpp"
|
||||||
#include "meta_base/fixed_function.hpp"
|
#include "meta_base/fixed_function.hpp"
|
||||||
#include "meta_base/hash_combiner.hpp"
|
#include "meta_base/hash_combiner.hpp"
|
||||||
|
#include "meta_base/insert_or_assign.hpp"
|
||||||
#include "meta_base/is_in_place_type.hpp"
|
#include "meta_base/is_in_place_type.hpp"
|
||||||
#include "meta_base/memory_buffer.hpp"
|
#include "meta_base/memory_buffer.hpp"
|
||||||
#include "meta_base/noncopyable.hpp"
|
#include "meta_base/noncopyable.hpp"
|
||||||
|
|||||||
44
headers/meta.hpp/meta_base/insert_or_assign.hpp
Normal file
44
headers/meta.hpp/meta_base/insert_or_assign.hpp
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* This file is part of the "https://github.com/blackmatov/meta.hpp"
|
||||||
|
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||||
|
* Copyright (C) 2021-2023, by Matvey Cherevko (blackmatov@gmail.com)
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "base.hpp"
|
||||||
|
|
||||||
|
namespace meta_hpp::detail
|
||||||
|
{
|
||||||
|
template < typename Key, typename Compare, typename Allocator >
|
||||||
|
typename std::set<Key, Compare, Allocator>::iterator
|
||||||
|
insert_or_assign(std::set<Key, Compare, Allocator>& set,
|
||||||
|
typename std::set<Key, Compare, Allocator>::value_type&& value)
|
||||||
|
{
|
||||||
|
auto&& [position, inserted] = set.insert(std::move(value));
|
||||||
|
|
||||||
|
if ( inserted ) {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto node = set.extract(position++);
|
||||||
|
node.value() = std::move(value);
|
||||||
|
return set.insert(position, std::move(node));
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename Key, typename Compare, typename Allocator >
|
||||||
|
typename std::set<Key, Compare, Allocator>::iterator
|
||||||
|
insert_or_assign(std::set<Key, Compare, Allocator>& set,
|
||||||
|
const typename std::set<Key, Compare, Allocator>::value_type& value)
|
||||||
|
{
|
||||||
|
auto&& [position, inserted] = set.insert(value);
|
||||||
|
|
||||||
|
if ( inserted ) {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto node = set.extract(position++);
|
||||||
|
node.value() = value;
|
||||||
|
return set.insert(position, std::move(node));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user