2017-04-04 17:28:01 +00:00
|
|
|
/** @defgroup Containers
|
2015-04-05 23:05:21 +00:00
|
|
|
*
|
2017-04-04 17:28:01 +00:00
|
|
|
* @brief New containers and extensions to standard containers.
|
|
|
|
*
|
2017-04-06 18:14:52 +00:00
|
|
|
* libostd adds various new utilities for standard containers that allow
|
2017-04-04 17:28:01 +00:00
|
|
|
* besides other things construction of those containers from ranges.
|
|
|
|
*
|
|
|
|
* Integration of ranges for iteration is however not necessary because
|
|
|
|
* there is already a fully generic integration for anything that provides
|
|
|
|
* an iterator interface.
|
|
|
|
*
|
|
|
|
* New containers will also be implemented where necessary.
|
|
|
|
*
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
|
|
|
|
/** @file vector.hh
|
|
|
|
*
|
|
|
|
* @brief Extensions for std::vector.
|
|
|
|
*
|
|
|
|
* This file provides extensions for the standard std::vector container.
|
|
|
|
*
|
|
|
|
* @copyright See COPYING.md in the project tree for further information.
|
2015-04-05 23:05:21 +00:00
|
|
|
*/
|
|
|
|
|
2015-07-13 19:08:55 +00:00
|
|
|
#ifndef OSTD_VECTOR_HH
|
|
|
|
#define OSTD_VECTOR_HH
|
2015-04-05 23:05:21 +00:00
|
|
|
|
2017-01-25 00:44:22 +00:00
|
|
|
#include <vector>
|
2017-02-01 19:56:19 +00:00
|
|
|
#include <memory>
|
2017-02-01 17:28:57 +00:00
|
|
|
#include <type_traits>
|
2015-04-14 21:16:06 +00:00
|
|
|
|
2015-07-13 19:08:55 +00:00
|
|
|
#include "ostd/range.hh"
|
2015-04-05 23:05:21 +00:00
|
|
|
|
2015-07-13 19:07:14 +00:00
|
|
|
namespace ostd {
|
2015-06-03 23:06:43 +00:00
|
|
|
|
2017-04-04 17:28:01 +00:00
|
|
|
/** @addtogroup Containers
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
|
|
|
|
/** @brief Creates a vector using a range.
|
|
|
|
*
|
|
|
|
* Given a range `range` and optionally an allocator, this constructs
|
|
|
|
* an std::vector, adding each item of the given range to it.
|
|
|
|
*
|
|
|
|
* You have to manually specify the type of the vector's values. There
|
|
|
|
* is also another version with the type decided from the range.
|
|
|
|
*
|
|
|
|
* @tparam T The value type of the vector.
|
|
|
|
*/
|
2017-02-01 19:56:19 +00:00
|
|
|
template<typename T, typename A = std::allocator<T>, typename R>
|
|
|
|
inline std::vector<T, A> make_vector(R range, A const &alloc = A{}) {
|
|
|
|
std::vector<T, A> ret{alloc};
|
2017-02-16 19:02:55 +00:00
|
|
|
using C = range_category_t<R>;
|
2017-04-04 17:28:01 +00:00
|
|
|
if constexpr(std::is_convertible_v<C, contiguous_range_tag>) {
|
2017-02-01 19:56:19 +00:00
|
|
|
ret.reserve(range.size());
|
2017-04-04 17:28:01 +00:00
|
|
|
ret.insert(ret.end(), range.data(), range.data() + range.size());
|
2017-02-01 17:28:57 +00:00
|
|
|
} else {
|
|
|
|
for (; !range.empty(); range.pop_front()) {
|
|
|
|
ret.push_back(range.front());
|
|
|
|
}
|
2017-01-25 00:44:22 +00:00
|
|
|
}
|
|
|
|
return ret;
|
2015-07-12 23:24:14 +00:00
|
|
|
}
|
|
|
|
|
2017-04-04 17:28:01 +00:00
|
|
|
/** @brief Creates a vector using a range.
|
|
|
|
*
|
|
|
|
* Calls into make_vector() using the range value type as the vector
|
|
|
|
* value type.
|
|
|
|
*/
|
2017-02-16 19:02:55 +00:00
|
|
|
template<typename R, typename A = std::allocator<range_value_t<R>>>
|
|
|
|
inline std::vector<range_value_t<R>, A> make_vector(
|
2017-02-01 19:56:19 +00:00
|
|
|
R &&range, A const &alloc = A{}
|
|
|
|
) {
|
2017-02-16 19:02:55 +00:00
|
|
|
return make_vector<range_value_t<R>, A>(std::forward<R>(range), alloc);
|
2015-07-12 23:24:14 +00:00
|
|
|
}
|
|
|
|
|
2017-04-04 17:28:01 +00:00
|
|
|
/** @} */
|
|
|
|
|
2015-07-13 19:07:14 +00:00
|
|
|
} /* namespace ostd */
|
2015-04-05 23:05:21 +00:00
|
|
|
|
2016-02-07 21:17:15 +00:00
|
|
|
#endif
|
2017-04-04 17:28:01 +00:00
|
|
|
|
|
|
|
/** @} */
|