libostd/ostd/vector.hh

85 lines
2.2 KiB
C++
Raw Normal View History

2017-04-04 19:28:01 +02:00
/** @defgroup Containers
2015-04-06 01:05:21 +02:00
*
2017-04-04 19:28:01 +02:00
* @brief New containers and extensions to standard containers.
*
2017-04-06 20:14:52 +02:00
* libostd adds various new utilities for standard containers that allow
2017-04-04 19:28:01 +02: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-06 01:05:21 +02:00
*/
2015-07-13 21:08:55 +02:00
#ifndef OSTD_VECTOR_HH
#define OSTD_VECTOR_HH
2015-04-06 01:05:21 +02:00
2017-01-25 01:44:22 +01:00
#include <vector>
#include <memory>
#include <type_traits>
2015-04-14 23:16:06 +02:00
2015-07-13 21:08:55 +02:00
#include "ostd/range.hh"
2015-04-06 01:05:21 +02:00
2015-07-13 21:07:14 +02:00
namespace ostd {
2015-06-04 01:06:43 +02:00
2017-04-04 19:28:01 +02: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.
*/
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};
using C = range_category_t<R>;
2017-04-04 19:28:01 +02:00
if constexpr(std::is_convertible_v<C, contiguous_range_tag>) {
ret.reserve(range.size());
2017-04-04 19:28:01 +02:00
ret.insert(ret.end(), range.data(), range.data() + range.size());
} else {
for (; !range.empty(); range.pop_front()) {
ret.push_back(range.front());
}
2017-01-25 01:44:22 +01:00
}
return ret;
2015-07-13 01:24:14 +02:00
}
2017-04-04 19:28:01 +02:00
/** @brief Creates a vector using a range.
*
* Calls into make_vector() using the range value type as the vector
* value type.
*/
template<typename R, typename A = std::allocator<range_value_t<R>>>
inline std::vector<range_value_t<R>, A> make_vector(
R &&range, A const &alloc = A{}
) {
return make_vector<range_value_t<R>, A>(std::forward<R>(range), alloc);
2015-07-13 01:24:14 +02:00
}
2017-04-04 19:28:01 +02:00
/** @} */
2015-07-13 21:07:14 +02:00
} /* namespace ostd */
2015-04-06 01:05:21 +02:00
2016-02-07 22:17:15 +01:00
#endif
2017-04-04 19:28:01 +02:00
/** @} */