I want to create a class Entity that can be templated for owning and non-owning string types (e.g. std::string or std::string_view). In both cases though there is internal datastructure to be allocated (vector) which needs an allocator, however in the string case I want to use the same allocator for the internal data structure as the string and have the Entity constructor forward this allocator to the string object. In the string_view case, the constructor of string_view doesn't take an allocator, so I would have to specialize the call to the constructor to NOT forward the allocator but initialize empty. I can get close with uses_allocator_construction_args but I can't unpack the tuple into the parameter list, what can I do instead?
Here's what I have and want to do:
#include <iostream>
#include <vector>
#include <string>
#include <string_view>
template <typename Allocator>
struct view_adapter {
using string_type = std::string_view;
using allocator_type = Allocator;
};
template <typename StringType>
struct string_type_of_or {
using type = StringType;
};
template <typename Allocator>
struct string_type_of_or<view_adapter<Allocator>> {
using type = view_adapter<Allocator>::string_type;
};
template <typename StringType>
struct Entity {
using allocator_type = StringType::allocator_type;
using string_type = string_type_of_or<StringType>::type;
Entity(allocator_type allocator = {})
: vec{ allocator }
, str{ uses_allocator_construction_args<StringType>(allocator)... } // <---- How to write this?
{}
StringType str;
std::vector<StringType,
typename std::allocator_traits<allocator_type>::template rebind_alloc<StringType>> vec;
};
int main() {
Entity<std::string> my_val;
Entity<view_adapter<std::allocator<std::string_view::value_type>>> my_view;
}