config/Data: use std::forward_list to manage params and blocks

This commit is contained in:
Max Kellermann
2018-07-18 11:03:19 +02:00
parent fd80683ade
commit 9ff2606bb8
11 changed files with 85 additions and 116 deletions
-5
View File
@@ -78,11 +78,6 @@ BlockParam::GetBoolValue() const
return value2;
}
ConfigBlock::~ConfigBlock()
{
delete next;
}
const BlockParam *
ConfigBlock::GetBlockParam(const char *name) const noexcept
{
+2 -11
View File
@@ -55,12 +55,6 @@ struct BlockParam {
};
struct ConfigBlock {
/**
* The next #ConfigBlock with the same name. The destructor
* deletes the whole chain.
*/
ConfigBlock *next = nullptr;
int line;
std::vector<BlockParam> block_params;
@@ -74,11 +68,8 @@ struct ConfigBlock {
explicit ConfigBlock(int _line=-1)
:line(_line) {}
ConfigBlock(const ConfigBlock &) = delete;
~ConfigBlock();
ConfigBlock &operator=(const ConfigBlock &) = delete;
ConfigBlock(ConfigBlock &&) = default;
ConfigBlock &operator=(ConfigBlock &&) = default;
/**
* Determine if this is a "null" instance, i.e. an empty
+26 -42
View File
@@ -19,8 +19,6 @@
#include "config.h"
#include "Data.hxx"
#include "Param.hxx"
#include "Block.hxx"
#include "Parser.hxx"
#include "fs/AllocatedPath.hxx"
#include "util/RuntimeError.hxx"
@@ -31,35 +29,36 @@
void
ConfigData::Clear()
{
for (auto &i : params) {
delete i;
i = nullptr;
}
for (auto &i : params)
i.clear();
for (auto &i : blocks) {
delete i;
i = nullptr;
}
for (auto &i : blocks)
i.clear();
}
gcc_nonnull_all
static void
Append(ConfigParam *&head, ConfigParam *p)
template<typename T>
gcc_pure
static auto
FindLast(const std::forward_list<T> &list)
{
assert(p->next == nullptr);
auto i = list.before_begin();
while (std::next(i) != list.end())
++i;
return i;
}
auto **i = &head;
while (*i != nullptr)
i = &(*i)->next;
*i = p;
template<typename T>
static auto
Append(std::forward_list<T> &list, T &&src)
{
return list.emplace_after(FindLast(list), std::move(src));
}
void
ConfigData::AddParam(ConfigOption option,
std::unique_ptr<ConfigParam> param) noexcept
{
Append(params[size_t(option)], param.release());
Append(GetParamList(option), std::move(*param));
}
const char *
@@ -143,39 +142,25 @@ ConfigData::GetBool(ConfigOption option, bool default_value) const
return value;
}
gcc_nonnull_all
static void
Append(ConfigBlock *&head, ConfigBlock *p)
{
assert(p->next == nullptr);
auto **i = &head;
while (*i != nullptr)
i = &(*i)->next;
*i = p;
}
void
ConfigBlock &
ConfigData::AddBlock(ConfigBlockOption option,
std::unique_ptr<ConfigBlock> block) noexcept
{
Append(blocks[size_t(option)], block.release());
return *Append(GetBlockList(option), std::move(*block));
}
const ConfigBlock *
ConfigData::FindBlock(ConfigBlockOption option,
const char *key, const char *value) const
{
for (const auto *block = GetBlock(option);
block != nullptr; block = block->next) {
const char *value2 = block->GetBlockValue(key);
for (const auto &block : GetBlockList(option)) {
const char *value2 = block.GetBlockValue(key);
if (value2 == nullptr)
throw FormatRuntimeError("block without '%s' in line %d",
key, block->line);
key, block.line);
if (StringIsEqual(value2, value))
return block;
return &block;
}
return nullptr;
@@ -189,8 +174,7 @@ ConfigData::MakeBlock(ConfigBlockOption option,
if (block == nullptr) {
auto new_block = std::make_unique<ConfigBlock>();
new_block->AddBlockParam(key, value);
block = new_block.get();
AddBlock(option, std::move(new_block));
block = &AddBlock(option, std::move(new_block));
}
return *block;
+27 -6
View File
@@ -21,9 +21,12 @@
#define MPD_CONFIG_DATA_HXX
#include "Option.hxx"
#include "Param.hxx"
#include "Block.hxx"
#include <array>
#include <chrono>
#include <forward_list>
#include <memory>
struct ConfigParam;
@@ -31,17 +34,26 @@ struct ConfigBlock;
class AllocatedPath;
struct ConfigData {
std::array<ConfigParam *, std::size_t(ConfigOption::MAX)> params{{nullptr}};
std::array<ConfigBlock *, std::size_t(ConfigBlockOption::MAX)> blocks{{nullptr}};
std::array<std::forward_list<ConfigParam>, std::size_t(ConfigOption::MAX)> params;
std::array<std::forward_list<ConfigBlock>, std::size_t(ConfigBlockOption::MAX)> blocks;
void Clear();
auto &GetParamList(ConfigOption option) noexcept {
return params[size_t(option)];
}
const auto &GetParamList(ConfigOption option) const noexcept {
return params[size_t(option)];
}
void AddParam(ConfigOption option,
std::unique_ptr<ConfigParam> param) noexcept;
gcc_pure
const ConfigParam *GetParam(ConfigOption option) const noexcept {
return params[size_t(option)];
const auto &list = GetParamList(option);
return list.empty() ? nullptr : &list.front();
}
gcc_pure
@@ -81,12 +93,21 @@ struct ConfigData {
bool GetBool(ConfigOption option, bool default_value) const;
void AddBlock(ConfigBlockOption option,
std::unique_ptr<ConfigBlock> block) noexcept;
auto &GetBlockList(ConfigBlockOption option) noexcept {
return blocks[size_t(option)];
}
const auto &GetBlockList(ConfigBlockOption option) const noexcept {
return blocks[size_t(option)];
}
ConfigBlock &AddBlock(ConfigBlockOption option,
std::unique_ptr<ConfigBlock> block) noexcept;
gcc_pure
const ConfigBlock *GetBlock(ConfigBlockOption option) const noexcept {
return blocks[size_t(option)];
const auto &list = GetBlockList(option);
return list.empty() ? nullptr : &list.front();
}
/**
+3 -3
View File
@@ -72,9 +72,9 @@ Check(const ConfigBlock &block)
void config_global_check(void)
{
for (auto i : config_data.blocks)
for (const auto *p = i; p != nullptr; p = p->next)
Check(*p);
for (const auto &list : config_data.blocks)
for (const auto &block : list)
Check(block);
}
const char *
-5
View File
@@ -25,11 +25,6 @@
#include <stdexcept>
ConfigParam::~ConfigParam()
{
delete next;
}
AllocatedPath
ConfigParam::GetPath() const
{
+2 -11
View File
@@ -28,12 +28,6 @@
class AllocatedPath;
struct ConfigParam {
/**
* The next ConfigParam with the same name. The destructor
* deletes the whole chain.
*/
ConfigParam *next = nullptr;
std::string value;
int line;
@@ -46,11 +40,8 @@ struct ConfigParam {
explicit ConfigParam(V &&_value, int _line=-1) noexcept
:value(std::forward<V>(_value)), line(_line) {}
ConfigParam(const ConfigParam &) = delete;
~ConfigParam();
ConfigParam &operator=(const ConfigParam &) = delete;
ConfigParam(ConfigParam &&) = default;
ConfigParam &operator=(ConfigParam &&) = default;
/**
* Determine if this is a "null" instance, i.e. an empty