mirror of
https://github.com/ToruNiina/toml11.git
synced 2025-09-16 08:27:31 +08:00
feat: Merge branch 'access-check'
This commit is contained in:
9
.github/workflows/main.yml
vendored
9
.github/workflows/main.yml
vendored
@@ -10,6 +10,7 @@ jobs:
|
||||
compiler: ['g++-12', 'g++-11', 'g++-10', 'g++-9']
|
||||
standard: ['11', '14', '17', '20']
|
||||
precompile: ['ON', 'OFF']
|
||||
betafeature: ['ON', 'OFF']
|
||||
steps:
|
||||
- name: Get number of CPU cores
|
||||
uses: SimenB/github-actions-cpu-cores@v2
|
||||
@@ -25,7 +26,7 @@ jobs:
|
||||
sudo apt-get install ${{ matrix.compiler }}
|
||||
- name: Configure
|
||||
run: |
|
||||
cmake -B build/ -DCMAKE_CXX_COMPILER=${{ matrix.compiler }} -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_BUILD_TESTS=ON -DTOML11_PRECOMPILE=${{ matrix.precompile }}
|
||||
cmake -B build/ -DCMAKE_CXX_COMPILER=${{ matrix.compiler }} -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_BUILD_TESTS=ON -DTOML11_PRECOMPILE=${{ matrix.precompile }} -DTOML11_ENABLE_ACCESS_CHECK=${{ matrix.betafeature }}
|
||||
- name: Build
|
||||
run: |
|
||||
cmake --build build/ -j${{ steps.cpu-cores.outputs.count }}
|
||||
@@ -141,6 +142,7 @@ jobs:
|
||||
matrix:
|
||||
standard: ['11', '14', '17', '20']
|
||||
precompile: ['ON', 'OFF']
|
||||
betafeature: ['ON', 'OFF']
|
||||
steps:
|
||||
- name: Get number of CPU cores
|
||||
uses: SimenB/github-actions-cpu-cores@v2
|
||||
@@ -151,7 +153,7 @@ jobs:
|
||||
submodules: true
|
||||
- name: Configure
|
||||
run: |
|
||||
cmake -B build/ -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_BUILD_TESTS=ON -DTOML11_PRECOMPILE=${{ matrix.precompile }}
|
||||
cmake -B build/ -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_BUILD_TESTS=ON -DTOML11_PRECOMPILE=${{ matrix.precompile }} -DTOML11_ENABLE_ACCESS_CHECK=${{ matrix.betafeature }}
|
||||
- name: Build
|
||||
run: |
|
||||
cmake --build build/ -j${{ steps.cpu-cores.outputs.count }}
|
||||
@@ -190,6 +192,7 @@ jobs:
|
||||
standard: ['11', '14', '17', '20']
|
||||
config: ['Release', 'Debug']
|
||||
precompile: ['ON', 'OFF']
|
||||
betafeature: ['ON', 'OFF']
|
||||
steps:
|
||||
- name: Get number of CPU cores
|
||||
uses: SimenB/github-actions-cpu-cores@v2
|
||||
@@ -202,7 +205,7 @@ jobs:
|
||||
- name: Configure
|
||||
shell: cmd
|
||||
run: |
|
||||
cmake -B build/ -G "NMake Makefiles" -DTOML11_BUILD_TESTS=ON -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_PRECOMPILE=${{ matrix.precompile }}
|
||||
cmake -B build/ -G "NMake Makefiles" -DTOML11_BUILD_TESTS=ON -DCMAKE_CXX_STANDARD=${{ matrix.standard }} -DTOML11_PRECOMPILE=${{ matrix.precompile }} -DTOML11_ENABLE_ACCESS_CHECK=${{ matrix.betafeature }}
|
||||
- name: Build
|
||||
run: |
|
||||
cmake --build ./build --config "${{ matrix.config }}" -j${{ steps.cpu-cores.outputs.count }}
|
||||
|
@@ -17,6 +17,7 @@ project(toml11 LANGUAGES CXX VERSION "${TOML11_VERSION_MAJOR}.${TOML11_VERSION_M
|
||||
include(CTest) # to use ${BUILD_TESTING}
|
||||
|
||||
option(TOML11_PRECOMPILE "precompile toml11 library" OFF)
|
||||
option(TOML11_ENABLE_ACCESS_CHECK "enable access check feature (beta)" OFF)
|
||||
|
||||
include(CMakeDependentOption)
|
||||
cmake_policy(PUSH)
|
||||
|
@@ -834,3 +834,76 @@ struct bar
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
# Checking Whether a Value Has Been Accessed
|
||||
|
||||
{{% hint warning %}}
|
||||
|
||||
This feature is not enabled by default. To use it, you need to define `TOML11_ENABLE_ACCESS_CHECK`.
|
||||
Additionally, since this feature introduces extra processing on parsed values, it may impact runtime performance.
|
||||
|
||||
{{% /hint %}}
|
||||
|
||||
When compiled with the `TOML11_ENABLE_ACCESS_CHECK` macro defined, the `toml::value` class gains an additional method: `bool accessed() const`.
|
||||
This allows you to check whether a value has been accessed after parsing.
|
||||
|
||||
```console
|
||||
$ g++ -std=c++17 -O2 -DTOML11_ENABLE_ACCESS_CHECK -I/path/to/toml11/include main.cpp
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```console
|
||||
$ cmake -B ./build -DTOML11_ENABLE_ACCESS_CHECK=ON
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```cmake
|
||||
CPMAddPackage(
|
||||
NAME toml11
|
||||
GITHUB_REPOSITORY "ToruNiina/toml11"
|
||||
VERSION 4.4.0
|
||||
OPTIONS "CMAKE_CXX_STANDARD 17" "TOML11_PRECOMPILE ON" "TOML11_ENABLE_ACCESS_CHECK ON"
|
||||
)
|
||||
```
|
||||
|
||||
This feature allows users to implement code that warns about values defined in a table but never used.
|
||||
|
||||
```cpp
|
||||
#include <toml.hpp>
|
||||
|
||||
namespace yours
|
||||
{
|
||||
|
||||
Config read_config(const toml::value& input)
|
||||
{
|
||||
const auto cfg = read_your_config(input);
|
||||
|
||||
for (const auto& [k, v] : input.as_table())
|
||||
{
|
||||
if (!v.accessed())
|
||||
{
|
||||
std::cerr << toml::format_error("value defined but not used",
|
||||
v.source_location(), "not used");
|
||||
}
|
||||
}
|
||||
return cfg;
|
||||
}
|
||||
} // namespace yours
|
||||
```
|
||||
|
||||
This feature is useful when a value is mistakenly defined under the wrong name but is never accessed. For example:
|
||||
|
||||
```toml
|
||||
# The correct key is "reactions"
|
||||
# reactions = [ ":+1:", "star" ]
|
||||
|
||||
# This key is incorrect and will not be read
|
||||
reaction = [ ":+1:", "star" ]
|
||||
```
|
||||
|
||||
If this file is read using the above code, `read_your_config` will search for `reactions`. Since it is not defined, it will process `reactions` as an empty array.
|
||||
In this case, `input.at("reaction").accessed()` will be `false`, allowing it to be detected as an error.
|
||||
|
||||
|
||||
|
@@ -863,3 +863,71 @@ struct bar
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
# 値がアクセス済みかどうかチェックする
|
||||
|
||||
{{% hint warning %}}
|
||||
|
||||
この機能はデフォルトでは有効化されず、使用する際には`TOML11_ENABLE_ACCESS_CHECK`を定義する必要があります。
|
||||
また、この機能はパースした値に対して追加の処理を行うため、実行時パフォーマンスが低下する可能性があります。
|
||||
|
||||
{{% /hint %}}
|
||||
|
||||
`TOML11_ENABLE_ACCESS_CHECK`マクロを定義してコンパイルすると、`toml::value`に`bool accessed() const`メソッドが追加され、パース後にその値にアクセスしたかどうかが確認できるようになります。
|
||||
|
||||
```console
|
||||
$ g++ -std=c++17 -O2 -DTOML11_ENABLE_ACCESS_CHECK -I/path/to/toml11/include main.cpp
|
||||
```
|
||||
|
||||
```console
|
||||
$ cmake -B ./build -DTOML11_ENABLE_ACCESS_CHECK=ON
|
||||
```
|
||||
|
||||
```cmake
|
||||
CPMAddPackage(
|
||||
NAME toml11
|
||||
GITHUB_REPOSITORY "ToruNiina/toml11"
|
||||
VERSION 4.4.0
|
||||
OPTIONS "CMAKE_CXX_STANDARD 17" "TOML11_PRECOMPILE ON" "TOML11_ENABLE_ACCESS_CHECK ON"
|
||||
)
|
||||
```
|
||||
|
||||
この機能によって、テーブル内に定義されているものの使用されなかった値についての警告を表示することが可能になります。
|
||||
|
||||
```cpp
|
||||
#include <toml.hpp>
|
||||
|
||||
namespace yours
|
||||
{
|
||||
|
||||
Config read_config(const toml::value& v)
|
||||
{
|
||||
const auto cfg = read_your_config(input);
|
||||
|
||||
for(const auto& [k, v] : input.as_table())
|
||||
{
|
||||
if( ! v.accessed())
|
||||
{
|
||||
std::cerr << toml::format_error("value defined but not used",
|
||||
v.source_location(), "not used");
|
||||
}
|
||||
}
|
||||
return cfg;
|
||||
}
|
||||
} // yours
|
||||
```
|
||||
|
||||
この機能は、必要な場合のみ定義されるような値を、名称を間違えて定義してしまった際に役に立つでしょう。
|
||||
例えば、
|
||||
|
||||
```toml
|
||||
# 正しくは reactions
|
||||
# reactions = [ ":+1:", "star" ]
|
||||
|
||||
# 名前が違うので読み込めない
|
||||
reaction = [ ":+1:", "star" ]
|
||||
```
|
||||
|
||||
このファイルを上記のコードで読んだ場合、`read_your_config`は`reactions`を探し、定義されていなかったので空の配列として処理するでしょう。
|
||||
その場合、`reaction`は`accessed()`が`true`にならないため、エラーとして検出できます。
|
||||
|
||||
|
@@ -3426,6 +3426,11 @@ parse_file(location& loc, context<TC>& ctx)
|
||||
{
|
||||
return err(std::move(ctx.errors()));
|
||||
}
|
||||
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
detail::unset_access_flag_recursively(root);
|
||||
#endif
|
||||
|
||||
return ok(std::move(root));
|
||||
}
|
||||
|
||||
|
@@ -17,6 +17,10 @@
|
||||
#include <string_view>
|
||||
#endif
|
||||
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
#include <atomic>
|
||||
#endif
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace toml
|
||||
@@ -55,6 +59,11 @@ void change_region_of_value(basic_value<TC>&, const basic_value<TC>&);
|
||||
|
||||
template<typename TC, value_t V>
|
||||
struct getter;
|
||||
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
template<typename TC>
|
||||
void unset_access_flag(basic_value<TC>&);
|
||||
#endif
|
||||
} // detail
|
||||
|
||||
template<typename TypeConfig>
|
||||
@@ -86,6 +95,9 @@ class basic_value
|
||||
|
||||
basic_value() noexcept
|
||||
: type_(value_t::empty), empty_('\0'), region_{}, comments_{}
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
, accessed_{false}
|
||||
#endif
|
||||
{}
|
||||
~basic_value() noexcept {this->cleanup();}
|
||||
|
||||
@@ -93,6 +105,9 @@ class basic_value
|
||||
|
||||
basic_value(const basic_value& v)
|
||||
: type_(v.type_), region_(v.region_), comments_(v.comments_)
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
, accessed_{v.accessed()}
|
||||
#endif
|
||||
{
|
||||
switch(this->type_)
|
||||
{
|
||||
@@ -112,6 +127,9 @@ class basic_value
|
||||
basic_value(basic_value&& v)
|
||||
: type_(v.type()), region_(std::move(v.region_)),
|
||||
comments_(std::move(v.comments_))
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
, accessed_{v.accessed()}
|
||||
#endif
|
||||
{
|
||||
switch(this->type_)
|
||||
{
|
||||
@@ -137,6 +155,9 @@ class basic_value
|
||||
this->type_ = v.type_;
|
||||
this->region_ = v.region_;
|
||||
this->comments_ = v.comments_;
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
this->accessed_ = v.accessed();
|
||||
#endif
|
||||
switch(this->type_)
|
||||
{
|
||||
case value_t::boolean : assigner(boolean_ , v.boolean_ ); break;
|
||||
@@ -161,6 +182,9 @@ class basic_value
|
||||
this->type_ = v.type_;
|
||||
this->region_ = std::move(v.region_);
|
||||
this->comments_ = std::move(v.comments_);
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
this->accessed_ = v.accessed();
|
||||
#endif
|
||||
switch(this->type_)
|
||||
{
|
||||
case value_t::boolean : assigner(boolean_ , std::move(v.boolean_ )); break;
|
||||
@@ -184,6 +208,9 @@ class basic_value
|
||||
basic_value(basic_value v, std::vector<std::string> com)
|
||||
: type_(v.type()), region_(std::move(v.region_)),
|
||||
comments_(std::move(com))
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
, accessed_{v.accessed()}
|
||||
#endif
|
||||
{
|
||||
switch(this->type_)
|
||||
{
|
||||
@@ -209,6 +236,9 @@ class basic_value
|
||||
: type_(other.type_),
|
||||
region_(std::move(other.region_)),
|
||||
comments_(std::move(other.comments_))
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
, accessed_{other.accessed()}
|
||||
#endif
|
||||
{
|
||||
switch(other.type_)
|
||||
{
|
||||
@@ -254,6 +284,9 @@ class basic_value
|
||||
: type_(other.type_),
|
||||
region_(std::move(other.region_)),
|
||||
comments_(std::move(com))
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
, accessed_{other.accessed()}
|
||||
#endif
|
||||
{
|
||||
switch(other.type_)
|
||||
{
|
||||
@@ -300,6 +333,10 @@ class basic_value
|
||||
this->region_ = other.region_;
|
||||
this->comments_ = comment_type(other.comments_);
|
||||
this->type_ = other.type_;
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
this->accessed_ = other.accessed();
|
||||
#endif
|
||||
|
||||
switch(other.type_)
|
||||
{
|
||||
// use auto-convert in constructor
|
||||
@@ -359,6 +396,9 @@ class basic_value
|
||||
std::vector<std::string> com, region_type reg)
|
||||
: type_(value_t::boolean), boolean_(boolean_storage(x, fmt)),
|
||||
region_(std::move(reg)), comments_(std::move(com))
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
, accessed_{false}
|
||||
#endif
|
||||
{}
|
||||
basic_value& operator=(boolean_type x)
|
||||
{
|
||||
@@ -370,6 +410,9 @@ class basic_value
|
||||
this->cleanup();
|
||||
this->type_ = value_t::boolean;
|
||||
this->region_ = region_type{};
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
this->accessed_ = false;
|
||||
#endif
|
||||
assigner(this->boolean_, boolean_storage(x, fmt));
|
||||
return *this;
|
||||
}
|
||||
@@ -393,6 +436,9 @@ class basic_value
|
||||
basic_value(integer_type x, integer_format_info fmt, std::vector<std::string> com, region_type reg)
|
||||
: type_(value_t::integer), integer_(integer_storage(std::move(x), std::move(fmt))),
|
||||
region_(std::move(reg)), comments_(std::move(com))
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
, accessed_{false}
|
||||
#endif
|
||||
{}
|
||||
basic_value& operator=(integer_type x)
|
||||
{
|
||||
@@ -404,6 +450,9 @@ class basic_value
|
||||
this->cleanup();
|
||||
this->type_ = value_t::integer;
|
||||
this->region_ = region_type{};
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
this->accessed_ = false;
|
||||
#endif
|
||||
assigner(this->integer_, integer_storage(std::move(x), std::move(fmt)));
|
||||
return *this;
|
||||
}
|
||||
@@ -439,6 +488,9 @@ class basic_value
|
||||
basic_value(T x, integer_format_info fmt, std::vector<std::string> com, region_type reg)
|
||||
: type_(value_t::integer), integer_(integer_storage(std::move(x), std::move(fmt))),
|
||||
region_(std::move(reg)), comments_(std::move(com))
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
, accessed_{false}
|
||||
#endif
|
||||
{}
|
||||
template<typename T, enable_if_integer_like_t<T> = nullptr>
|
||||
basic_value& operator=(T x)
|
||||
@@ -451,6 +503,9 @@ class basic_value
|
||||
this->cleanup();
|
||||
this->type_ = value_t::integer;
|
||||
this->region_ = region_type{};
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
this->accessed_ = false;
|
||||
#endif
|
||||
assigner(this->integer_, integer_storage(x, std::move(fmt)));
|
||||
return *this;
|
||||
}
|
||||
@@ -474,6 +529,9 @@ class basic_value
|
||||
basic_value(floating_type x, floating_format_info fmt, std::vector<std::string> com, region_type reg)
|
||||
: type_(value_t::floating), floating_(floating_storage(std::move(x), std::move(fmt))),
|
||||
region_(std::move(reg)), comments_(std::move(com))
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
, accessed_{false}
|
||||
#endif
|
||||
{}
|
||||
basic_value& operator=(floating_type x)
|
||||
{
|
||||
@@ -485,6 +543,9 @@ class basic_value
|
||||
this->cleanup();
|
||||
this->type_ = value_t::floating;
|
||||
this->region_ = region_type{};
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
this->accessed_ = false;
|
||||
#endif
|
||||
assigner(this->floating_, floating_storage(std::move(x), std::move(fmt)));
|
||||
return *this;
|
||||
}
|
||||
@@ -523,6 +584,9 @@ class basic_value
|
||||
basic_value(T x, floating_format_info fmt, std::vector<std::string> com, region_type reg)
|
||||
: type_(value_t::floating), floating_(floating_storage(x, std::move(fmt))),
|
||||
region_(std::move(reg)), comments_(std::move(com))
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
, accessed_{false}
|
||||
#endif
|
||||
{}
|
||||
|
||||
template<typename T, enable_if_floating_like_t<T> = nullptr>
|
||||
@@ -536,6 +600,9 @@ class basic_value
|
||||
this->cleanup();
|
||||
this->type_ = value_t::floating;
|
||||
this->region_ = region_type{};
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
this->accessed_ = false;
|
||||
#endif
|
||||
assigner(this->floating_, floating_storage(x, std::move(fmt)));
|
||||
return *this;
|
||||
}
|
||||
@@ -560,6 +627,9 @@ class basic_value
|
||||
std::vector<std::string> com, region_type reg)
|
||||
: type_(value_t::string), string_(string_storage(std::move(x), std::move(fmt))),
|
||||
region_(std::move(reg)), comments_(std::move(com))
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
, accessed_{false}
|
||||
#endif
|
||||
{}
|
||||
basic_value& operator=(string_type x)
|
||||
{
|
||||
@@ -571,6 +641,9 @@ class basic_value
|
||||
this->cleanup();
|
||||
this->type_ = value_t::string;
|
||||
this->region_ = region_type{};
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
this->accessed_ = false;
|
||||
#endif
|
||||
assigner(this->string_, string_storage(x, std::move(fmt)));
|
||||
return *this;
|
||||
}
|
||||
@@ -593,6 +666,9 @@ class basic_value
|
||||
std::vector<std::string> com, region_type reg)
|
||||
: type_(value_t::string), string_(string_storage(string_type(x), std::move(fmt))),
|
||||
region_(std::move(reg)), comments_(std::move(com))
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
, accessed_{false}
|
||||
#endif
|
||||
{}
|
||||
basic_value& operator=(const typename string_type::value_type* x)
|
||||
{
|
||||
@@ -604,6 +680,9 @@ class basic_value
|
||||
this->cleanup();
|
||||
this->type_ = value_t::string;
|
||||
this->region_ = region_type{};
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
this->accessed_ = false;
|
||||
#endif
|
||||
assigner(this->string_, string_storage(string_type(x), std::move(fmt)));
|
||||
return *this;
|
||||
}
|
||||
@@ -628,6 +707,9 @@ class basic_value
|
||||
std::vector<std::string> com, region_type reg)
|
||||
: type_(value_t::string), string_(string_storage(string_type(x), std::move(fmt))),
|
||||
region_(std::move(reg)), comments_(std::move(com))
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
, accessed_{false}
|
||||
#endif
|
||||
{}
|
||||
basic_value& operator=(string_view_type x)
|
||||
{
|
||||
@@ -639,6 +721,9 @@ class basic_value
|
||||
this->cleanup();
|
||||
this->type_ = value_t::string;
|
||||
this->region_ = region_type{};
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
this->accessed_ = false;
|
||||
#endif
|
||||
assigner(this->string_, string_storage(string_type(x), std::move(fmt)));
|
||||
return *this;
|
||||
}
|
||||
@@ -682,6 +767,9 @@ class basic_value
|
||||
: type_(value_t::string),
|
||||
string_(string_storage(detail::string_conv<string_type>(x), std::move(fmt))),
|
||||
region_(std::move(reg)), comments_(std::move(com))
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
, accessed_{false}
|
||||
#endif
|
||||
{}
|
||||
template<typename T, cxx::enable_if_t<cxx::conjunction<
|
||||
cxx::negation<std::is_same<cxx::remove_cvref_t<T>, string_type>>,
|
||||
@@ -697,6 +785,9 @@ class basic_value
|
||||
this->cleanup();
|
||||
this->type_ = value_t::string;
|
||||
this->region_ = region_type{};
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
this->accessed_ = false;
|
||||
#endif
|
||||
assigner(this->string_, string_storage(detail::string_conv<string_type>(x), std::move(fmt)));
|
||||
return *this;
|
||||
}
|
||||
@@ -721,6 +812,9 @@ class basic_value
|
||||
std::vector<std::string> com, region_type reg)
|
||||
: type_(value_t::local_date), local_date_(local_date_storage(x, fmt)),
|
||||
region_(std::move(reg)), comments_(std::move(com))
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
, accessed_{false}
|
||||
#endif
|
||||
{}
|
||||
basic_value& operator=(local_date_type x)
|
||||
{
|
||||
@@ -732,6 +826,9 @@ class basic_value
|
||||
this->cleanup();
|
||||
this->type_ = value_t::local_date;
|
||||
this->region_ = region_type{};
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
this->accessed_ = false;
|
||||
#endif
|
||||
assigner(this->local_date_, local_date_storage(x, fmt));
|
||||
return *this;
|
||||
}
|
||||
@@ -756,6 +853,9 @@ class basic_value
|
||||
std::vector<std::string> com, region_type reg)
|
||||
: type_(value_t::local_time), local_time_(local_time_storage(x, fmt)),
|
||||
region_(std::move(reg)), comments_(std::move(com))
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
, accessed_{false}
|
||||
#endif
|
||||
{}
|
||||
basic_value& operator=(local_time_type x)
|
||||
{
|
||||
@@ -767,6 +867,9 @@ class basic_value
|
||||
this->cleanup();
|
||||
this->type_ = value_t::local_time;
|
||||
this->region_ = region_type{};
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
this->accessed_ = false;
|
||||
#endif
|
||||
assigner(this->local_time_, local_time_storage(x, fmt));
|
||||
return *this;
|
||||
}
|
||||
@@ -804,6 +907,9 @@ class basic_value
|
||||
this->cleanup();
|
||||
this->type_ = value_t::local_time;
|
||||
this->region_ = region_type{};
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
this->accessed_ = false;
|
||||
#endif
|
||||
assigner(this->local_time_, local_time_storage(local_time_type(x), std::move(fmt)));
|
||||
return *this;
|
||||
}
|
||||
@@ -828,6 +934,9 @@ class basic_value
|
||||
std::vector<std::string> com, region_type reg)
|
||||
: type_(value_t::local_datetime), local_datetime_(local_datetime_storage(x, fmt)),
|
||||
region_(std::move(reg)), comments_(std::move(com))
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
, accessed_{false}
|
||||
#endif
|
||||
{}
|
||||
basic_value& operator=(local_datetime_type x)
|
||||
{
|
||||
@@ -839,6 +948,9 @@ class basic_value
|
||||
this->cleanup();
|
||||
this->type_ = value_t::local_datetime;
|
||||
this->region_ = region_type{};
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
this->accessed_ = false;
|
||||
#endif
|
||||
assigner(this->local_datetime_, local_datetime_storage(x, fmt));
|
||||
return *this;
|
||||
}
|
||||
@@ -863,6 +975,9 @@ class basic_value
|
||||
std::vector<std::string> com, region_type reg)
|
||||
: type_(value_t::offset_datetime), offset_datetime_(offset_datetime_storage(x, fmt)),
|
||||
region_(std::move(reg)), comments_(std::move(com))
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
, accessed_{false}
|
||||
#endif
|
||||
{}
|
||||
basic_value& operator=(offset_datetime_type x)
|
||||
{
|
||||
@@ -874,6 +989,9 @@ class basic_value
|
||||
this->cleanup();
|
||||
this->type_ = value_t::offset_datetime;
|
||||
this->region_ = region_type{};
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
this->accessed_ = false;
|
||||
#endif
|
||||
assigner(this->offset_datetime_, offset_datetime_storage(x, fmt));
|
||||
return *this;
|
||||
}
|
||||
@@ -906,6 +1024,9 @@ class basic_value
|
||||
this->cleanup();
|
||||
this->type_ = value_t::offset_datetime;
|
||||
this->region_ = region_type{};
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
this->accessed_ = false;
|
||||
#endif
|
||||
assigner(this->offset_datetime_, offset_datetime_storage(offset_datetime_type(x), fmt));
|
||||
return *this;
|
||||
}
|
||||
@@ -931,6 +1052,9 @@ class basic_value
|
||||
: type_(value_t::array), array_(array_storage(
|
||||
detail::storage<array_type>(std::move(x)), std::move(fmt)
|
||||
)), region_(std::move(reg)), comments_(std::move(com))
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
, accessed_{false}
|
||||
#endif
|
||||
{}
|
||||
basic_value& operator=(array_type x)
|
||||
{
|
||||
@@ -942,6 +1066,9 @@ class basic_value
|
||||
this->cleanup();
|
||||
this->type_ = value_t::array;
|
||||
this->region_ = region_type{};
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
this->accessed_ = false;
|
||||
#endif
|
||||
assigner(this->array_, array_storage(
|
||||
detail::storage<array_type>(std::move(x)), std::move(fmt)));
|
||||
return *this;
|
||||
@@ -988,6 +1115,9 @@ class basic_value
|
||||
std::make_move_iterator(x.end()))
|
||||
), std::move(fmt)
|
||||
)), region_(std::move(reg)), comments_(std::move(com))
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
, accessed_{false}
|
||||
#endif
|
||||
{}
|
||||
template<typename T, enable_if_array_like_t<T> = nullptr>
|
||||
basic_value& operator=(T x)
|
||||
@@ -1000,7 +1130,9 @@ class basic_value
|
||||
this->cleanup();
|
||||
this->type_ = value_t::array;
|
||||
this->region_ = region_type{};
|
||||
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
this->accessed_ = false;
|
||||
#endif
|
||||
array_type a(std::make_move_iterator(x.begin()),
|
||||
std::make_move_iterator(x.end()));
|
||||
assigner(this->array_, array_storage(
|
||||
@@ -1029,6 +1161,9 @@ class basic_value
|
||||
: type_(value_t::table), table_(table_storage(
|
||||
detail::storage<table_type>(std::move(x)), std::move(fmt)
|
||||
)), region_(std::move(reg)), comments_(std::move(com))
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
, accessed_{false}
|
||||
#endif
|
||||
{}
|
||||
basic_value& operator=(table_type x)
|
||||
{
|
||||
@@ -1040,6 +1175,9 @@ class basic_value
|
||||
this->cleanup();
|
||||
this->type_ = value_t::table;
|
||||
this->region_ = region_type{};
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
this->accessed_ = false;
|
||||
#endif
|
||||
assigner(this->table_, table_storage(
|
||||
detail::storage<table_type>(std::move(x)), std::move(fmt)));
|
||||
return *this;
|
||||
@@ -1084,6 +1222,9 @@ class basic_value
|
||||
std::make_move_iterator(x.end())
|
||||
)), std::move(fmt)
|
||||
)), region_(std::move(reg)), comments_(std::move(com))
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
, accessed_{false}
|
||||
#endif
|
||||
{}
|
||||
template<typename T, enable_if_table_like_t<T> = nullptr>
|
||||
basic_value& operator=(T x)
|
||||
@@ -1096,7 +1237,9 @@ class basic_value
|
||||
this->cleanup();
|
||||
this->type_ = value_t::table;
|
||||
this->region_ = region_type{};
|
||||
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
this->accessed_ = false;
|
||||
#endif
|
||||
table_type t(std::make_move_iterator(x.begin()),
|
||||
std::make_move_iterator(x.end()));
|
||||
assigner(this->table_, table_storage(
|
||||
@@ -1126,6 +1269,9 @@ class basic_value
|
||||
basic_value& operator=(const T& ud)
|
||||
{
|
||||
*this = into<cxx::remove_cvref_t<T>>::template into_toml<config_type>(ud);
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
this->accessed_ = false;
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -1149,6 +1295,9 @@ class basic_value
|
||||
basic_value& operator=(const T& ud)
|
||||
{
|
||||
*this = ud.into_toml();
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
this->accessed_ = false;
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -1172,6 +1321,9 @@ class basic_value
|
||||
basic_value& operator=(const T& ud)
|
||||
{
|
||||
*this = ud.template into_toml<TypeConfig>();
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
this->accessed_ = false;
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
// }}}
|
||||
@@ -1181,6 +1333,9 @@ class basic_value
|
||||
// mainly for `null` extension
|
||||
basic_value(detail::none_t, region_type reg) noexcept
|
||||
: type_(value_t::empty), empty_('\0'), region_(std::move(reg)), comments_{}
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
, accessed_{false}
|
||||
#endif
|
||||
{}
|
||||
|
||||
// }}}
|
||||
@@ -1192,9 +1347,13 @@ class basic_value
|
||||
std::nullptr_t> = nullptr>
|
||||
bool is() const noexcept
|
||||
{
|
||||
return detail::type_to_enum<T, value_type>::value == this->type_;
|
||||
return this->is(detail::type_to_enum<T, value_type>::value);
|
||||
}
|
||||
bool is(value_t t) const noexcept
|
||||
{
|
||||
this->set_accessed();
|
||||
return t == this->type_;
|
||||
}
|
||||
bool is(value_t t) const noexcept {return t == this->type_;}
|
||||
|
||||
bool is_empty() const noexcept {return this->is(value_t::empty );}
|
||||
bool is_boolean() const noexcept {return this->is(value_t::boolean );}
|
||||
@@ -1210,6 +1369,7 @@ class basic_value
|
||||
|
||||
bool is_array_of_tables() const noexcept
|
||||
{
|
||||
this->set_accessed();
|
||||
if( ! this->is_array()) {return false;}
|
||||
const auto& a = this->as_array(std::nothrow); // already checked.
|
||||
|
||||
@@ -1229,7 +1389,11 @@ class basic_value
|
||||
return true;
|
||||
}
|
||||
|
||||
value_t type() const noexcept {return type_;}
|
||||
value_t type() const noexcept
|
||||
{
|
||||
this->set_accessed();
|
||||
return type_;
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
@@ -1239,36 +1403,38 @@ class basic_value
|
||||
detail::enum_to_type_t<T, basic_value<config_type>> const&
|
||||
as(const std::nothrow_t&) const noexcept
|
||||
{
|
||||
this->set_accessed();
|
||||
return detail::getter<config_type, T>::get_nothrow(*this);
|
||||
}
|
||||
template<value_t T>
|
||||
detail::enum_to_type_t<T, basic_value<config_type>>&
|
||||
as(const std::nothrow_t&) noexcept
|
||||
{
|
||||
this->set_accessed();
|
||||
return detail::getter<config_type, T>::get_nothrow(*this);
|
||||
}
|
||||
|
||||
boolean_type const& as_boolean (const std::nothrow_t&) const noexcept {return this->boolean_.value;}
|
||||
integer_type const& as_integer (const std::nothrow_t&) const noexcept {return this->integer_.value;}
|
||||
floating_type const& as_floating (const std::nothrow_t&) const noexcept {return this->floating_.value;}
|
||||
string_type const& as_string (const std::nothrow_t&) const noexcept {return this->string_.value;}
|
||||
offset_datetime_type const& as_offset_datetime(const std::nothrow_t&) const noexcept {return this->offset_datetime_.value;}
|
||||
local_datetime_type const& as_local_datetime (const std::nothrow_t&) const noexcept {return this->local_datetime_.value;}
|
||||
local_date_type const& as_local_date (const std::nothrow_t&) const noexcept {return this->local_date_.value;}
|
||||
local_time_type const& as_local_time (const std::nothrow_t&) const noexcept {return this->local_time_.value;}
|
||||
array_type const& as_array (const std::nothrow_t&) const noexcept {return this->array_.value.get();}
|
||||
table_type const& as_table (const std::nothrow_t&) const noexcept {return this->table_.value.get();}
|
||||
boolean_type const& as_boolean (const std::nothrow_t&) const noexcept {this->set_accessed(); return this->boolean_.value;}
|
||||
integer_type const& as_integer (const std::nothrow_t&) const noexcept {this->set_accessed(); return this->integer_.value;}
|
||||
floating_type const& as_floating (const std::nothrow_t&) const noexcept {this->set_accessed(); return this->floating_.value;}
|
||||
string_type const& as_string (const std::nothrow_t&) const noexcept {this->set_accessed(); return this->string_.value;}
|
||||
offset_datetime_type const& as_offset_datetime(const std::nothrow_t&) const noexcept {this->set_accessed(); return this->offset_datetime_.value;}
|
||||
local_datetime_type const& as_local_datetime (const std::nothrow_t&) const noexcept {this->set_accessed(); return this->local_datetime_.value;}
|
||||
local_date_type const& as_local_date (const std::nothrow_t&) const noexcept {this->set_accessed(); return this->local_date_.value;}
|
||||
local_time_type const& as_local_time (const std::nothrow_t&) const noexcept {this->set_accessed(); return this->local_time_.value;}
|
||||
array_type const& as_array (const std::nothrow_t&) const noexcept {this->set_accessed(); return this->array_.value.get();}
|
||||
table_type const& as_table (const std::nothrow_t&) const noexcept {this->set_accessed(); return this->table_.value.get();}
|
||||
|
||||
boolean_type & as_boolean (const std::nothrow_t&) noexcept {return this->boolean_.value;}
|
||||
integer_type & as_integer (const std::nothrow_t&) noexcept {return this->integer_.value;}
|
||||
floating_type & as_floating (const std::nothrow_t&) noexcept {return this->floating_.value;}
|
||||
string_type & as_string (const std::nothrow_t&) noexcept {return this->string_.value;}
|
||||
offset_datetime_type& as_offset_datetime(const std::nothrow_t&) noexcept {return this->offset_datetime_.value;}
|
||||
local_datetime_type & as_local_datetime (const std::nothrow_t&) noexcept {return this->local_datetime_.value;}
|
||||
local_date_type & as_local_date (const std::nothrow_t&) noexcept {return this->local_date_.value;}
|
||||
local_time_type & as_local_time (const std::nothrow_t&) noexcept {return this->local_time_.value;}
|
||||
array_type & as_array (const std::nothrow_t&) noexcept {return this->array_.value.get();}
|
||||
table_type & as_table (const std::nothrow_t&) noexcept {return this->table_.value.get();}
|
||||
boolean_type & as_boolean (const std::nothrow_t&) noexcept {this->set_accessed(); return this->boolean_.value;}
|
||||
integer_type & as_integer (const std::nothrow_t&) noexcept {this->set_accessed(); return this->integer_.value;}
|
||||
floating_type & as_floating (const std::nothrow_t&) noexcept {this->set_accessed(); return this->floating_.value;}
|
||||
string_type & as_string (const std::nothrow_t&) noexcept {this->set_accessed(); return this->string_.value;}
|
||||
offset_datetime_type& as_offset_datetime(const std::nothrow_t&) noexcept {this->set_accessed(); return this->offset_datetime_.value;}
|
||||
local_datetime_type & as_local_datetime (const std::nothrow_t&) noexcept {this->set_accessed(); return this->local_datetime_.value;}
|
||||
local_date_type & as_local_date (const std::nothrow_t&) noexcept {this->set_accessed(); return this->local_date_.value;}
|
||||
local_time_type & as_local_time (const std::nothrow_t&) noexcept {this->set_accessed(); return this->local_time_.value;}
|
||||
array_type & as_array (const std::nothrow_t&) noexcept {this->set_accessed(); return this->array_.value.get();}
|
||||
table_type & as_table (const std::nothrow_t&) noexcept {this->set_accessed(); return this->table_.value.get();}
|
||||
|
||||
// }}}
|
||||
|
||||
@@ -1291,6 +1457,7 @@ class basic_value
|
||||
{
|
||||
this->throw_bad_cast("toml::value::as_boolean()", value_t::boolean);
|
||||
}
|
||||
this->set_accessed();
|
||||
return this->boolean_.value;
|
||||
}
|
||||
integer_type const& as_integer() const
|
||||
@@ -1299,6 +1466,7 @@ class basic_value
|
||||
{
|
||||
this->throw_bad_cast("toml::value::as_integer()", value_t::integer);
|
||||
}
|
||||
this->set_accessed();
|
||||
return this->integer_.value;
|
||||
}
|
||||
floating_type const& as_floating() const
|
||||
@@ -1307,6 +1475,7 @@ class basic_value
|
||||
{
|
||||
this->throw_bad_cast("toml::value::as_floating()", value_t::floating);
|
||||
}
|
||||
this->set_accessed();
|
||||
return this->floating_.value;
|
||||
}
|
||||
string_type const& as_string() const
|
||||
@@ -1315,6 +1484,7 @@ class basic_value
|
||||
{
|
||||
this->throw_bad_cast("toml::value::as_string()", value_t::string);
|
||||
}
|
||||
this->set_accessed();
|
||||
return this->string_.value;
|
||||
}
|
||||
offset_datetime_type const& as_offset_datetime() const
|
||||
@@ -1323,6 +1493,7 @@ class basic_value
|
||||
{
|
||||
this->throw_bad_cast("toml::value::as_offset_datetime()", value_t::offset_datetime);
|
||||
}
|
||||
this->set_accessed();
|
||||
return this->offset_datetime_.value;
|
||||
}
|
||||
local_datetime_type const& as_local_datetime() const
|
||||
@@ -1331,6 +1502,7 @@ class basic_value
|
||||
{
|
||||
this->throw_bad_cast("toml::value::as_local_datetime()", value_t::local_datetime);
|
||||
}
|
||||
this->set_accessed();
|
||||
return this->local_datetime_.value;
|
||||
}
|
||||
local_date_type const& as_local_date() const
|
||||
@@ -1339,6 +1511,7 @@ class basic_value
|
||||
{
|
||||
this->throw_bad_cast("toml::value::as_local_date()", value_t::local_date);
|
||||
}
|
||||
this->set_accessed();
|
||||
return this->local_date_.value;
|
||||
}
|
||||
local_time_type const& as_local_time() const
|
||||
@@ -1347,6 +1520,7 @@ class basic_value
|
||||
{
|
||||
this->throw_bad_cast("toml::value::as_local_time()", value_t::local_time);
|
||||
}
|
||||
this->set_accessed();
|
||||
return this->local_time_.value;
|
||||
}
|
||||
array_type const& as_array() const
|
||||
@@ -1355,6 +1529,7 @@ class basic_value
|
||||
{
|
||||
this->throw_bad_cast("toml::value::as_array()", value_t::array);
|
||||
}
|
||||
this->set_accessed();
|
||||
return this->array_.value.get();
|
||||
}
|
||||
table_type const& as_table() const
|
||||
@@ -1363,6 +1538,7 @@ class basic_value
|
||||
{
|
||||
this->throw_bad_cast("toml::value::as_table()", value_t::table);
|
||||
}
|
||||
this->set_accessed();
|
||||
return this->table_.value.get();
|
||||
}
|
||||
|
||||
@@ -1375,6 +1551,7 @@ class basic_value
|
||||
{
|
||||
this->throw_bad_cast("toml::value::as_boolean()", value_t::boolean);
|
||||
}
|
||||
this->set_accessed();
|
||||
return this->boolean_.value;
|
||||
}
|
||||
integer_type& as_integer()
|
||||
@@ -1383,6 +1560,7 @@ class basic_value
|
||||
{
|
||||
this->throw_bad_cast("toml::value::as_integer()", value_t::integer);
|
||||
}
|
||||
this->set_accessed();
|
||||
return this->integer_.value;
|
||||
}
|
||||
floating_type& as_floating()
|
||||
@@ -1391,6 +1569,7 @@ class basic_value
|
||||
{
|
||||
this->throw_bad_cast("toml::value::as_floating()", value_t::floating);
|
||||
}
|
||||
this->set_accessed();
|
||||
return this->floating_.value;
|
||||
}
|
||||
string_type& as_string()
|
||||
@@ -1399,6 +1578,7 @@ class basic_value
|
||||
{
|
||||
this->throw_bad_cast("toml::value::as_string()", value_t::string);
|
||||
}
|
||||
this->set_accessed();
|
||||
return this->string_.value;
|
||||
}
|
||||
offset_datetime_type& as_offset_datetime()
|
||||
@@ -1407,6 +1587,7 @@ class basic_value
|
||||
{
|
||||
this->throw_bad_cast("toml::value::as_offset_datetime()", value_t::offset_datetime);
|
||||
}
|
||||
this->set_accessed();
|
||||
return this->offset_datetime_.value;
|
||||
}
|
||||
local_datetime_type& as_local_datetime()
|
||||
@@ -1415,6 +1596,7 @@ class basic_value
|
||||
{
|
||||
this->throw_bad_cast("toml::value::as_local_datetime()", value_t::local_datetime);
|
||||
}
|
||||
this->set_accessed();
|
||||
return this->local_datetime_.value;
|
||||
}
|
||||
local_date_type& as_local_date()
|
||||
@@ -1423,6 +1605,7 @@ class basic_value
|
||||
{
|
||||
this->throw_bad_cast("toml::value::as_local_date()", value_t::local_date);
|
||||
}
|
||||
this->set_accessed();
|
||||
return this->local_date_.value;
|
||||
}
|
||||
local_time_type& as_local_time()
|
||||
@@ -1431,6 +1614,7 @@ class basic_value
|
||||
{
|
||||
this->throw_bad_cast("toml::value::as_local_time()", value_t::local_time);
|
||||
}
|
||||
this->set_accessed();
|
||||
return this->local_time_.value;
|
||||
}
|
||||
array_type& as_array()
|
||||
@@ -1439,6 +1623,7 @@ class basic_value
|
||||
{
|
||||
this->throw_bad_cast("toml::value::as_array()", value_t::array);
|
||||
}
|
||||
this->set_accessed();
|
||||
return this->array_.value.get();
|
||||
}
|
||||
table_type& as_table()
|
||||
@@ -1447,6 +1632,7 @@ class basic_value
|
||||
{
|
||||
this->throw_bad_cast("toml::value::as_table()", value_t::table);
|
||||
}
|
||||
this->set_accessed();
|
||||
return this->table_.value.get();
|
||||
}
|
||||
|
||||
@@ -1856,10 +2042,22 @@ class basic_value
|
||||
comment_type const& comments() const noexcept {return this->comments_;}
|
||||
comment_type& comments() noexcept {return this->comments_;}
|
||||
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
bool accessed() const {return this->accessed_.load();}
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
// private helper functions =========================================== {{{
|
||||
|
||||
void set_accessed() const noexcept
|
||||
{
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
this->accessed_.store(true);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
void cleanup() noexcept
|
||||
{
|
||||
switch(this->type_)
|
||||
@@ -1876,6 +2074,9 @@ class basic_value
|
||||
case value_t::table : { table_ .~table_storage (); break; }
|
||||
default : { break; }
|
||||
}
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
this->accessed_ = false;
|
||||
#endif
|
||||
this->type_ = value_t::empty;
|
||||
return;
|
||||
}
|
||||
@@ -1908,6 +2109,12 @@ class basic_value
|
||||
template<typename TC>
|
||||
friend class basic_value;
|
||||
|
||||
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
template<typename TC>
|
||||
friend void detail::unset_access_flag(basic_value<TC>&);
|
||||
#endif
|
||||
|
||||
// }}}
|
||||
|
||||
private:
|
||||
@@ -1942,6 +2149,10 @@ class basic_value
|
||||
};
|
||||
region_type region_;
|
||||
comment_type comments_;
|
||||
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
mutable std::atomic<bool> accessed_;
|
||||
#endif
|
||||
};
|
||||
|
||||
template<typename TC>
|
||||
@@ -2252,6 +2463,48 @@ void change_region_of_value(basic_value<TC>& dst, const basic_value<TC>& src)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
template<typename TC>
|
||||
void unset_access_flag(basic_value<TC>& v)
|
||||
{
|
||||
v.accessed_.store(false);
|
||||
}
|
||||
|
||||
template<typename TC>
|
||||
void unset_access_flag_recursively(basic_value<TC>& v)
|
||||
{
|
||||
switch(v.type())
|
||||
{
|
||||
case value_t::empty : { return unset_access_flag(v); }
|
||||
case value_t::boolean : { return unset_access_flag(v); }
|
||||
case value_t::integer : { return unset_access_flag(v); }
|
||||
case value_t::floating : { return unset_access_flag(v); }
|
||||
case value_t::string : { return unset_access_flag(v); }
|
||||
case value_t::offset_datetime : { return unset_access_flag(v); }
|
||||
case value_t::local_datetime : { return unset_access_flag(v); }
|
||||
case value_t::local_date : { return unset_access_flag(v); }
|
||||
case value_t::local_time : { return unset_access_flag(v); }
|
||||
case value_t::array:
|
||||
{
|
||||
for(auto& elem : v.as_array())
|
||||
{
|
||||
unset_access_flag_recursively(elem);
|
||||
}
|
||||
return unset_access_flag(v);
|
||||
}
|
||||
case value_t::table:
|
||||
{
|
||||
for(auto& kv : v.as_table())
|
||||
{
|
||||
unset_access_flag_recursively(kv.second);
|
||||
}
|
||||
return unset_access_flag(v);
|
||||
}
|
||||
default: { return unset_access_flag(v); }
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
} // namespace toml
|
||||
#endif // TOML11_VALUE_HPP
|
||||
|
@@ -90,7 +90,10 @@ if(TOML11_PRECOMPILE)
|
||||
types.cpp
|
||||
value_t.cpp
|
||||
)
|
||||
target_compile_definitions(toml11 PUBLIC -DTOML11_COMPILE_SOURCES)
|
||||
target_compile_definitions(toml11 PUBLIC
|
||||
-DTOML11_COMPILE_SOURCES
|
||||
$<$<BOOL:${TOML11_ENABLE_ACCESS_CHECK}>: -DTOML11_ENABLE_ACCESS_CHECK>
|
||||
)
|
||||
target_include_directories(toml11 PUBLIC
|
||||
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
|
||||
$<INSTALL_INTERFACE:include>
|
||||
@@ -127,6 +130,9 @@ if(TOML11_PRECOMPILE)
|
||||
endif()
|
||||
else()
|
||||
add_library(toml11 INTERFACE)
|
||||
target_compile_definitions(toml11 INTERFACE
|
||||
$<$<BOOL:${TOML11_ENABLE_ACCESS_CHECK}>: -DTOML11_ENABLE_ACCESS_CHECK>
|
||||
)
|
||||
target_include_directories(toml11 INTERFACE
|
||||
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
|
||||
$<INSTALL_INTERFACE:include>
|
||||
|
@@ -39,6 +39,7 @@ set(TOML11_TEST_NAMES
|
||||
test_utility
|
||||
test_user_defined_conversion
|
||||
test_value
|
||||
test_accessed
|
||||
test_visit
|
||||
)
|
||||
|
||||
|
76
tests/test_accessed.cpp
Normal file
76
tests/test_accessed.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
|
||||
#include "doctest.h"
|
||||
|
||||
#include <toml.hpp>
|
||||
|
||||
#ifdef TOML11_ENABLE_ACCESS_CHECK
|
||||
|
||||
TEST_CASE("testing toml::parse(file)")
|
||||
{
|
||||
using namespace toml::literals::toml_literals;
|
||||
|
||||
const std::string spec_example(R"(# This is a TOML document
|
||||
|
||||
title = "TOML Example"
|
||||
|
||||
[owner]
|
||||
name = "Tom Preston-Werner"
|
||||
dob = 1979-05-27T07:32:00-08:00
|
||||
|
||||
[database]
|
||||
enabled = true
|
||||
ports = [ 8000, 8001, 8002 ]
|
||||
data = [ ["delta", "phi"], [3.14] ]
|
||||
temp_targets = { cpu = 79.5, case = 72.0 }
|
||||
|
||||
[servers]
|
||||
|
||||
[servers.alpha]
|
||||
ip = "10.0.0.1"
|
||||
role = "frontend"
|
||||
|
||||
[servers.beta]
|
||||
ip = "10.0.0.2"
|
||||
role = "backend"
|
||||
)");
|
||||
|
||||
const auto u = toml::parse_str(spec_example);
|
||||
|
||||
CHECK_EQ(u.at("title").as_string(), "TOML Example");
|
||||
CHECK_EQ(u.at("owner").at("name").as_string(), "Tom Preston-Werner");
|
||||
|
||||
CHECK_EQ(u.at("database").at("ports").at(0).as_integer(), 8000);
|
||||
CHECK_EQ(u.at("database").at("ports").at(1).as_integer(), 8001);
|
||||
CHECK_EQ(u.at("database").at("data").at(0).at(1).as_string(), "phi");
|
||||
|
||||
CHECK_EQ(u.at("servers").at("alpha").at("ip" ).as_string(), "10.0.0.1");
|
||||
CHECK_EQ(u.at("servers").at("alpha").at("role").as_string(), "frontend");
|
||||
|
||||
CHECK_UNARY(u.accessed());
|
||||
CHECK_UNARY(u.at("title").accessed());
|
||||
CHECK_UNARY(u.at("owner").accessed());
|
||||
CHECK_UNARY(u.at("owner").at("name").accessed());
|
||||
CHECK_UNARY(u.at("servers").accessed());
|
||||
CHECK_UNARY(u.at("servers").at("alpha").accessed());
|
||||
CHECK_UNARY(u.at("servers").at("alpha").at("ip").accessed());
|
||||
CHECK_UNARY(u.at("servers").at("alpha").at("role").accessed());
|
||||
CHECK_UNARY(u.at("database").accessed());
|
||||
CHECK_UNARY(u.at("database").at("ports").accessed());
|
||||
CHECK_UNARY(u.at("database").at("ports").at(0).accessed());
|
||||
CHECK_UNARY(u.at("database").at("ports").at(1).accessed());
|
||||
|
||||
CHECK_UNARY_FALSE(u.at("owner").at("dob").accessed());
|
||||
CHECK_UNARY_FALSE(u.at("servers").at("beta").accessed());
|
||||
CHECK_UNARY_FALSE(u.at("servers").at("beta").at("ip").accessed());
|
||||
CHECK_UNARY_FALSE(u.at("servers").at("beta").at("role").accessed());
|
||||
|
||||
CHECK_UNARY_FALSE(u.at("database").at("enabled").accessed());
|
||||
CHECK_UNARY_FALSE(u.at("database").at("ports").at(2).accessed());
|
||||
CHECK_UNARY_FALSE(u.at("database").at("data").at(0).at(0).accessed());
|
||||
CHECK_UNARY_FALSE(u.at("database").at("data").at(1).at(0).accessed());
|
||||
CHECK_UNARY_FALSE(u.at("database").at("temp_targets").accessed());
|
||||
CHECK_UNARY_FALSE(u.at("database").at("temp_targets").at("cpu" ).accessed());
|
||||
CHECK_UNARY_FALSE(u.at("database").at("temp_targets").at("case").accessed());
|
||||
}
|
||||
|
||||
#endif // TOML11_ENABLE_ACCESS_CHECK
|
Reference in New Issue
Block a user