-
-
Save piotrkundu/6222c317b916883f4f08ab05db30a421 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// make_vector.hpp | |
// | |
// Copyright (c) 2019 Tristan Brindle (tcbrindle at gmail dot com) | |
// Distributed under the Boost Software License, Version 1.0. (See | |
// http://www.boost.org/LICENSE_1_0.txt) | |
#include <type_traits> | |
#include <vector> | |
namespace tcb { | |
namespace detail { | |
template <typename T, typename...> | |
struct vec_type_helper { | |
using type = T; | |
}; | |
template <typename... Args> | |
struct vec_type_helper<void, Args...> { | |
using type = typename std::common_type<Args...>::type; | |
}; | |
template <typename T, typename... Args> | |
using vec_type_helper_t = typename vec_type_helper<T, Args...>::type; | |
template <typename, typename...> | |
struct all_constructible_and_convertible | |
: std::true_type {}; | |
template <typename T, typename First, typename... Rest> | |
struct all_constructible_and_convertible<T, First, Rest...> | |
: std::conditional< | |
std::is_constructible<T, First>::value && | |
std::is_convertible<First, T>::value, | |
all_constructible_and_convertible<T, Rest...>, | |
std::false_type>::type {}; | |
template <typename T, typename... Args, typename std::enable_if< | |
!std::is_trivially_copyable<T>::value, int>::type = 0> | |
std::vector<T> make_vector_impl(Args&&... args) | |
{ | |
std::vector<T> vec; | |
vec.reserve(sizeof...(Args)); | |
using arr_t = int[]; | |
(void) arr_t{0, (vec.emplace_back(std::forward<Args>(args)), 0)...}; | |
return vec; | |
} | |
template <typename T, typename... Args, typename std::enable_if< | |
std::is_trivially_copyable<T>::value, int>::type = 0> | |
std::vector<T> make_vector_impl(Args&&... args) | |
{ | |
return std::vector<T>{std::forward<Args>(args)...}; | |
} | |
} // namespace detail | |
template <typename T = void, typename... Args, | |
typename V = detail::vec_type_helper_t<T, Args...>, | |
typename std::enable_if< | |
detail::all_constructible_and_convertible<V, Args...>::value, int>::type = 0> | |
std::vector<V> make_vector(Args&&... args) | |
{ | |
return detail::make_vector_impl<V>(std::forward<Args>(args)...); | |
} | |
} // namespace tcb |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment