more documentation
parent
9f35909660
commit
480b7a56a4
|
@ -1,6 +1,23 @@
|
|||
/* SDL RWops integration.
|
||||
/** @addtogroup Extensions
|
||||
*
|
||||
* This file is part of OctaSTD. See COPYING.md for futher information.
|
||||
* @brief Various extensions including integration of OctaSTD with other libs.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @file sdl_rwops.hh
|
||||
*
|
||||
* @brief Integration of OctaSTD streams with SDL RWops.
|
||||
*
|
||||
* This provides integration of OctaSTD streams with SDL RWops so that
|
||||
* various APIs that provide a generic RWops interface to deal with
|
||||
* files can use OctaSTD streams.
|
||||
*
|
||||
* Supports both SDL1 and SDL2, with SDL2 being default. If you want to
|
||||
* use SDL1 compatibility, define `OSTD_EXT_SDL_USE_SDL1` at build time
|
||||
* or before including this header.
|
||||
*
|
||||
* @copyright See COPYING.md in the project tree for further information.
|
||||
*/
|
||||
|
||||
#ifndef OSTD_EXT_SDL_RWOPS_HH
|
||||
|
@ -17,13 +34,27 @@
|
|||
namespace ostd {
|
||||
namespace sdl {
|
||||
|
||||
/** @addtogroup Extensions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @brief Create an `SDL_RWops` using an OctaSTD stream.
|
||||
*
|
||||
* The resulting RWops object is created using `SDL_AllocRW()`.
|
||||
*
|
||||
* The `size`, `seek`, `read`, `write` and `close` callbacks are set up,
|
||||
* but `close` will not actually close the stream, as the RWops object
|
||||
* does not take ownership.
|
||||
*
|
||||
* @returns The RWops object or `nullptr` on failure.
|
||||
*/
|
||||
inline SDL_RWops *stream_to_rwops(stream &s) noexcept {
|
||||
#ifdef OSTD_EXT_SDL_USE_SDL1
|
||||
using sdl_rwops_off_t = int;
|
||||
using sdl_rwops_off_t = int;
|
||||
#else
|
||||
using sdl_rwops_off_t = int64_t;
|
||||
using sdl_rwops_off_t = int64_t;
|
||||
#endif
|
||||
|
||||
inline SDL_RWops *stream_to_rwops(stream &s) {
|
||||
SDL_RWops *rwr = SDL_AllocRW();
|
||||
if (!rwr) {
|
||||
return nullptr;
|
||||
|
@ -46,7 +77,7 @@ inline SDL_RWops *stream_to_rwops(stream &s) {
|
|||
auto &is = *static_cast<stream *>(rw->hidden.unknown.data1);
|
||||
try {
|
||||
if (!pos && whence == SEEK_CUR) {
|
||||
return static_cast<sdl_rwops_off_t(is.tell());
|
||||
return static_cast<sdl_rwops_off_t>(is.tell());
|
||||
}
|
||||
if (is->seek((stream_off_t(pos), stream_seek(whence)))) {
|
||||
return static_cast<sdl_rwops_off_t>(is.tell());
|
||||
|
@ -89,4 +120,8 @@ inline SDL_RWops *stream_to_rwops(stream &s) {
|
|||
}
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
|
|
@ -354,13 +354,10 @@ template<
|
|||
inline std::basic_string<T, TR, A> make_string(R range, A const &alloc = A{}) {
|
||||
std::basic_string<T, TR, A> ret{alloc};
|
||||
using C = range_category_t<R>;
|
||||
if constexpr(std::is_convertible_v<C, finite_random_access_range_tag>) {
|
||||
/* finite random access or contiguous */
|
||||
auto h = range.half();
|
||||
if constexpr(std::is_convertible_v<C, contiguous_range_tag>) {
|
||||
ret.reserve(range.size());
|
||||
ret.insert(ret.end(), h, h + range.size());
|
||||
ret.insert(ret.end(), range.data(), range.data() + range.size());
|
||||
} else {
|
||||
/* infinite random access and below */
|
||||
for (; !range.empty(); range.pop_front()) {
|
||||
ret.push_back(range.front());
|
||||
}
|
||||
|
|
|
@ -1,6 +1,14 @@
|
|||
/* OctaSTD extensions for std::unordered_map.
|
||||
/** @addtogroup Containers
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @file unordered_map.hh
|
||||
*
|
||||
* This file is part of OctaSTD. See COPYING.md for futher information.
|
||||
* @brief Extensions for std::unordered_map.
|
||||
*
|
||||
* This file provides extensions for the standard std::unordered_map container.
|
||||
*
|
||||
* @copyright See COPYING.md in the project tree for further information.
|
||||
*/
|
||||
|
||||
#ifndef OSTD_UNORDERED_MAP_HH
|
||||
|
@ -13,6 +21,10 @@
|
|||
|
||||
namespace ostd {
|
||||
|
||||
/** @addtogroup Containers
|
||||
* @{
|
||||
*/
|
||||
|
||||
namespace detail {
|
||||
template<typename T>
|
||||
std::integral_constant<
|
||||
|
@ -26,6 +38,23 @@ namespace detail {
|
|||
constexpr bool is_2tuple_like = decltype(tuple2_like_test<T>(0))::value;
|
||||
}
|
||||
|
||||
/** @brief Creates an unordered map using a range.
|
||||
*
|
||||
* The range's value type must be either an std::pair or an std::tuple
|
||||
* with 2 elements, additionally the key and value types must be constructible
|
||||
* using the tuple or pair's first and second element respectively.
|
||||
*
|
||||
* You need to manually specify the key and value types for this overload.
|
||||
*
|
||||
* @param[in] range The range.
|
||||
* @param[in] bcount The initial bucket count.
|
||||
* @param[in] hash The hash function.
|
||||
* @param[in] kequal The key equality comparison function.
|
||||
* @param[in] alloc The allocator.
|
||||
*
|
||||
* @tparam K The key type.
|
||||
* @tparam V The value type.
|
||||
*/
|
||||
template<
|
||||
typename K, typename T, typename H = std::hash<K>,
|
||||
typename E = std::equal_to<K>,
|
||||
|
@ -72,6 +101,11 @@ inline std::unordered_map<K, T, H, E, A> make_unordered_map(
|
|||
return ret;
|
||||
}
|
||||
|
||||
/** @brief Creates an unordered map using a range.
|
||||
*
|
||||
* Calls into make_unordered_map() using the range value type's first and
|
||||
* second element types as key and value respectively.
|
||||
*/
|
||||
template<
|
||||
typename R,
|
||||
typename H = std::hash<typename range_value_t<R>::first_type>,
|
||||
|
@ -98,6 +132,10 @@ inline std::unordered_map<
|
|||
>(std::forward<R>(range), bcount, hash, kequal, alloc);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
} /* namespace ostd */
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
|
|
@ -1,6 +1,26 @@
|
|||
/* OctaSTD extensions for std::vector.
|
||||
/** @defgroup Containers
|
||||
*
|
||||
* This file is part of OctaSTD. See COPYING.md for futher information.
|
||||
* @brief New containers and extensions to standard containers.
|
||||
*
|
||||
* OctaSTD adds various new utilities for standard containers that allow
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef OSTD_VECTOR_HH
|
||||
|
@ -14,17 +34,28 @@
|
|||
|
||||
namespace ostd {
|
||||
|
||||
/** @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>;
|
||||
if constexpr(std::is_convertible_v<C, finite_random_access_range_tag>) {
|
||||
/* finite random access or contiguous */
|
||||
auto h = range.half();
|
||||
if constexpr(std::is_convertible_v<C, contiguous_range_tag>) {
|
||||
ret.reserve(range.size());
|
||||
ret.insert(ret.end(), h, h + range.size());
|
||||
ret.insert(ret.end(), range.data(), range.data() + range.size());
|
||||
} else {
|
||||
/* infinite random access and below */
|
||||
for (; !range.empty(); range.pop_front()) {
|
||||
ret.push_back(range.front());
|
||||
}
|
||||
|
@ -32,6 +63,11 @@ inline std::vector<T, A> make_vector(R range, A const &alloc = A{}) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
/** @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{}
|
||||
|
@ -39,6 +75,10 @@ inline std::vector<range_value_t<R>, A> make_vector(
|
|||
return make_vector<range_value_t<R>, A>(std::forward<R>(range), alloc);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
} /* namespace ostd */
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
|
Loading…
Reference in New Issue