diff --git a/include/boost/unordered/unordered_flat_set.hpp b/include/boost/unordered/unordered_flat_set.hpp new file mode 100644 index 00000000..ced04bfb --- /dev/null +++ b/include/boost/unordered/unordered_flat_set.hpp @@ -0,0 +1,186 @@ +// Copyright (C) 2022 Christian Mazakas +// 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) + +#ifndef BOOST_UNORDERED_UNORDERED_FLAT_SET_HPP_INCLUDED +#define BOOST_UNORDERED_UNORDERED_FLAT_SET_HPP_INCLUDED + +#include +#if defined(BOOST_HAS_PRAGMA_ONCE) +#pragma once +#endif + +#include +#include + +#include + +#include +#include +#include +#include + +namespace boost { + namespace unordered { + template + class unordered_flat_set + { + struct set_types + { + using key_type = Key; + using value_type = Key; + static Key const& extract(value_type const& key) { return key; } + }; + + using table_type = detail::foa::table::type>; + + table_type table_; + + public: + using key_type = Key; + using value_type = typename set_types::value_type; + using size_type = std::size_t; + using key_equal = KeyEqual; + using reference = value_type&; + using const_reference = value_type const&; + using iterator = typename table_type::iterator; + using const_iterator = typename table_type::const_iterator; + + iterator begin() noexcept { return table_.begin(); } + const_iterator begin() const noexcept { return table_.begin(); } + const_iterator cbegin() const noexcept { return table_.cbegin(); } + + iterator end() noexcept { return table_.end(); } + const_iterator end() const noexcept { return table_.end(); } + const_iterator cend() const noexcept { return table_.cend(); } + + /// Capacity + /// + + BOOST_ATTRIBUTE_NODISCARD bool empty() const noexcept + { + return table_.empty(); + } + + size_type size() const noexcept { return table_.size(); } + + /// Modifiers + /// + + void clear() noexcept { table_.clear(); } + + std::pair insert(value_type const& value) + { + return table_.insert(value); + } + + std::pair insert(value_type&& value) + { + return table_.insert(std::move(value)); + } + + iterator insert(const_iterator, value_type const& value) + { + return table_.insert(value).first; + } + + iterator insert(const_iterator, value_type&& value) + { + return table_.insert(std::move(value)).first; + } + + template + typename std::enable_if< + std::is_base_of::value, + void>::type + insert(ForwardIterator first, ForwardIterator last) + { + auto const len = std::distance(first, last); + table_.reserve(len); + for (auto pos = first; pos != last; ++pos) { + table_.insert(*pos); + } + } + + template + typename std::enable_if< + !std::is_base_of::value, + void>::type + insert(InputIterator first, InputIterator last) + { + for (auto pos = first; pos != last; ++pos) { + table_.insert(*pos); + } + } + + void insert(std::initializer_list ilist) + { + this->insert(ilist.begin(), ilist.end()); + } + + template std::pair emplace(Args&&... args) + { + return table_.emplace(std::forward(args)...); + } + + void erase(const_iterator pos) { return table_.erase(pos); } + size_type erase(key_type const& key) { return table_.erase(key); } + + /// Lookup + /// + + size_type count(key_type const& key) const + { + auto pos = table_.find(key); + return pos != table_.end() ? 1 : 0; + } + + iterator find(key_type const& key) { return table_.find(key); } + + const_iterator find(key_type const& key) const + { + return table_.find(key); + } + + std::pair equal_range(key_type const& key) + { + auto pos = table_.find(key); + if (pos == table_.end()) { + return {pos, pos}; + } + + auto next = pos; + ++next; + return {pos, next}; + } + + std::pair equal_range( + key_type const& key) const + { + auto pos = table_.find(key); + if (pos == table_.end()) { + return {pos, pos}; + } + + auto next = pos; + ++next; + return {pos, next}; + } + + size_type bucket_count() const noexcept { return table_.capacity(); } + + float load_factor() const noexcept { return table_.load_factor(); } + + float max_load_factor() const noexcept + { + return table_.max_load_factor(); + } + + key_equal key_eq() const { return table_.key_eq(); } + }; + } // namespace unordered +} // namespace boost + +#endif diff --git a/include/boost/unordered/unordered_flat_set_fwd.hpp b/include/boost/unordered/unordered_flat_set_fwd.hpp new file mode 100644 index 00000000..91550cc0 --- /dev/null +++ b/include/boost/unordered/unordered_flat_set_fwd.hpp @@ -0,0 +1,30 @@ + +// Copyright (C) 2022 Christian Mazakas +// 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) + +#ifndef BOOST_UNORDERED_FLAT_SET_FWD_HPP_INCLUDED +#define BOOST_UNORDERED_FLAT_SET_FWD_HPP_INCLUDED + +#include +#if defined(BOOST_HAS_PRAGMA_ONCE) +#pragma once +#endif + +#include +#include +#include +#include + +namespace boost { + namespace unordered { + template , + class KeyEqual = std::equal_to, + class Allocator = std::allocator > + class unordered_flat_set; + } + + using boost::unordered::unordered_flat_set; +} // namespace boost + +#endif diff --git a/include/boost/unordered_flat_set.hpp b/include/boost/unordered_flat_set.hpp new file mode 100644 index 00000000..6e2067f8 --- /dev/null +++ b/include/boost/unordered_flat_set.hpp @@ -0,0 +1,18 @@ + +// Copyright (C) 2022 Christian Mazakas +// 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) + +// See http://www.boost.org/libs/unordered for documentation + +#ifndef BOOST_UNORDERED_FLAT_SET_HPP_INCLUDED +#define BOOST_UNORDERED_FLAT_SET_HPP_INCLUDED + +#include +#if defined(BOOST_HAS_PRAGMA_ONCE) +#pragma once +#endif + +#include + +#endif // BOOST_UNORDERED_FLAT_SET_HPP_INCLUDED \ No newline at end of file