dxx-rebirth/common/include/physfs_list.h
Kp 3aef1ee569 Tighten PHYSFSX_counted_list_template reset rules
Prefer move-assignment over use of reset() so that the count cannot go
out of sync from the list.

Shorten lifetime of some lists.
2023-02-04 19:21:25 +00:00

94 lines
2.4 KiB
C++

/*
* This file is part of the DXX-Rebirth project <https://www.dxx-rebirth.com/>.
* It is copyright by its individual contributors, as recorded in the
* project's Git history. See COPYING.txt at the top level for license
* terms and a link to the Git history.
*/
#pragma once
#include <physfs.h>
typedef char file_extension_t[5];
#ifdef __cplusplus
#include <cstdint>
#include <memory>
#include "null_sentinel_iterator.h"
#include "dxxsconf.h"
#include "dsx-ns.h"
#include "fwd-partial_range.h"
#include <array>
#include "backports-ranges.h"
namespace dcx {
class PHYSFS_list_deleter
{
public:
void operator()(char **list) const
{
PHYSFS_freeList(list);
}
};
template <typename Deleter>
class PHYSFSX_uncounted_list_template : protected std::unique_ptr<char *[], Deleter>
{
using base_type = std::unique_ptr<char *[], Deleter>;
public:
typedef null_sentinel_iterator<char *> const_iterator;
using base_type::base_type;
using base_type::get;
using base_type::operator bool;
using base_type::operator[];
using base_type::release;
using base_type::reset;
const_iterator begin() const
{
return this->get();
}
const_iterator end() const
{
return {};
}
};
template <typename Deleter>
class PHYSFSX_counted_list_template : public PHYSFSX_uncounted_list_template<Deleter>
{
using base_type = PHYSFSX_uncounted_list_template<Deleter>;
std::size_t count = 0;
public:
/* Inherit the zero-argument form of reset(), for clearing a list.
* Override and delete the one-argument form, so that the list cannot be
* given new contents, with a potentially different length, using
* `reset(other_list);`
*/
using base_type::reset;
void reset(auto) = delete;
constexpr PHYSFSX_counted_list_template() = default;
constexpr PHYSFSX_counted_list_template(base_type &&base, std::size_t count) :
base_type{std::move(base)}, count{count}
{
}
std::size_t get_count() const
{
return count;
}
};
typedef PHYSFSX_uncounted_list_template<PHYSFS_list_deleter> PHYSFSX_uncounted_list;
typedef PHYSFSX_counted_list_template<PHYSFS_list_deleter> PHYSFSX_counted_list;
[[nodiscard]]
__attribute_nonnull()
PHYSFSX_uncounted_list PHYSFSX_findFiles(const char *path, ranges::subrange<const file_extension_t *> exts);
[[nodiscard]]
__attribute_nonnull()
PHYSFSX_uncounted_list PHYSFSX_findabsoluteFiles(const char *path, const char *realpath, ranges::subrange<const file_extension_t *> exts);
}
#endif