flat containers for library

This commit is contained in:
2019-05-28 01:07:19 +07:00
parent f4dc114bbb
commit f7def3ce0c
3 changed files with 50 additions and 57 deletions

View File

@@ -11,6 +11,8 @@
#include <3rdparty/variant/variant.hpp>
#include <3rdparty/flat.hpp/flat_set.hpp>
#include <3rdparty/flat.hpp/flat_map.hpp>
#include <3rdparty/flat.hpp/flat_multiset.hpp>
#include <3rdparty/flat.hpp/flat_multimap.hpp>
namespace e2d
{
@@ -72,6 +74,17 @@ namespace e2d
, typename Compare = std::less<>
, typename Container = vector<std::pair<Key, Value>> >
using flat_map = flat_hpp::flat_map<Key, Value, Compare, Container>;
template < typename Key
, typename Compare = std::less<>
, typename Container = vector<Key> >
using flat_multiset = flat_hpp::flat_multiset<Key, Compare, Container>;
template < typename Key
, typename Value
, typename Compare = std::less<>
, typename Container = vector<std::pair<Key, Value>> >
using flat_multimap = flat_hpp::flat_multimap<Key, Value, Compare, Container>;
}
namespace e2d::stdex

View File

@@ -131,39 +131,35 @@ namespace e2d
template < typename Asset, typename Nested = Asset >
typename Nested::load_result find_asset(str_view address) const;
private:
vector<std::pair<str, asset_ptr>> assets_;
};
//
// asset_dependency_base
//
class asset_dependency_base;
using asset_dependency_base_iptr = intrusive_ptr<asset_dependency_base>;
class asset_dependency_base
: private noncopyable
, public ref_counter<asset_dependency_base> {
public:
asset_dependency_base() = default;
virtual ~asset_dependency_base() noexcept = default;
virtual const str& main_address() const noexcept = 0;
virtual stdex::promise<asset_ptr> load_async(const library& library) = 0;
flat_multimap<str, asset_ptr> assets_;
};
//
// asset_dependency
//
class asset_dependency;
using asset_dependency_iptr = intrusive_ptr<asset_dependency>;
class asset_dependency
: private noncopyable
, public ref_counter<asset_dependency> {
public:
asset_dependency() = default;
virtual ~asset_dependency() noexcept = default;
virtual const str& main_address() const noexcept = 0;
virtual stdex::promise<asset_ptr> load_async(const library& library) = 0;
};
template < typename Asset >
class asset_dependency : public asset_dependency_base {
class typed_asset_dependency : public asset_dependency {
public:
using asset_type = Asset;
using load_result = typename Asset::load_result;
public:
asset_dependency(str_view address);
~asset_dependency() noexcept override;
typed_asset_dependency(str_view address);
~typed_asset_dependency() noexcept override;
const str& main_address() const noexcept override;
stdex::promise<asset_ptr> load_async(const library& library) override;
@@ -184,7 +180,7 @@ namespace e2d
asset_dependencies& add_dependency(str_view address);
stdex::promise<asset_group> load_async(const library& library) const;
private:
vector<asset_dependency_base_iptr> dependencies_;
flat_multimap<str, asset_dependency_iptr> dependencies_;
};
}

View File

@@ -236,12 +236,7 @@ namespace e2d
inline asset_group& asset_group::add_asset(str_view address, const asset_ptr& asset) {
str main_address = address::parent(address);
const auto iter = std::upper_bound(
assets_.begin(), assets_.end(), main_address,
[](const str& l, const auto& r){
return l < r.first;
});
assets_.insert(iter, std::make_pair(std::move(main_address), asset));
assets_.emplace(std::move(main_address), asset);
return *this;
}
@@ -249,12 +244,8 @@ namespace e2d
typename Nested::load_result asset_group::find_asset(str_view address) const {
const str main_address = address::parent(address);
const str nested_address = address::nested(address);
auto iter = std::lower_bound(
assets_.begin(), assets_.end(), main_address,
[](const auto& l, const str& r) noexcept {
return l.first < r;
});
for ( ; iter != assets_.end() && iter->first == main_address; ++iter ) {
const auto [first, last] = assets_.equal_range(main_address);
for ( auto iter = first; iter != last; ++iter ) {
asset_ptr main_asset = iter->second;
typename Asset::load_result typed_main_asset = dynamic_pointer_cast<Asset>(main_asset);
if ( !typed_main_asset ) {
@@ -275,20 +266,20 @@ namespace e2d
//
template < typename Asset >
asset_dependency<Asset>::asset_dependency(str_view address)
typed_asset_dependency<Asset>::typed_asset_dependency(str_view address)
: main_address_(address::parent(address)) {}
template < typename Asset >
asset_dependency<Asset>::~asset_dependency() noexcept = default;
typed_asset_dependency<Asset>::~typed_asset_dependency() noexcept = default;
template < typename Asset >
const str& asset_dependency<Asset>::main_address() const noexcept {
const str& typed_asset_dependency<Asset>::main_address() const noexcept {
return main_address_;
}
template < typename Asset >
stdex::promise<asset_ptr> asset_dependency<Asset>::load_async(const library& library) {
return library.load_main_asset_async<Asset>(main_address())
stdex::promise<asset_ptr> typed_asset_dependency<Asset>::load_async(const library& library) {
return library.load_main_asset_async<Asset>(main_address_)
.then([](const typename Asset::load_result& main_asset){
return asset_ptr(main_asset);
});
@@ -300,31 +291,24 @@ namespace e2d
template < typename Asset, typename Nested >
asset_dependencies& asset_dependencies::add_dependency(str_view address) {
asset_dependency_base_iptr dep(new asset_dependency<Asset>(address));
auto iter = std::upper_bound(
dependencies_.begin(), dependencies_.end(), dep->main_address(),
[](const str& l, const auto& r){
return l < r->main_address();
});
dependencies_.insert(iter, std::move(dep));
asset_dependency_iptr dep(new typed_asset_dependency<Asset>(address));
dependencies_.emplace(dep->main_address(), std::move(dep));
return *this;
}
inline stdex::promise<asset_group> asset_dependencies::load_async(const library& library) const {
vector<stdex::promise<std::pair<str, asset_ptr>>> promises;
promises.reserve(dependencies_.size());
std::transform(
dependencies_.begin(), dependencies_.end(), std::back_inserter(promises),
[&library](const asset_dependency_base_iptr& dep){
return dep->load_async(library)
.then([main_address = dep->main_address()](const asset_ptr& asset){
return std::make_pair(main_address, asset);
});
});
for ( const auto& [_, dep] : dependencies_ ) {
promises.push_back(dep->load_async(library).then([
dep = dep
](const asset_ptr& asset){
return std::make_pair(dep->main_address(), asset);
}));
}
return stdex::make_all_promise(std::move(promises))
.then([](const vector<std::pair<str, asset_ptr>>& results){
return asset_group()
.add_assets(results.begin(), results.end());
return asset_group().add_assets(results);
});
}
}