Skip to content

Commit

Permalink
feat: Merge branch 'access-check'
Browse files Browse the repository at this point in the history
  • Loading branch information
ToruNiina committed Feb 2, 2025
2 parents 0c5472e + 8043503 commit f64ef36
Show file tree
Hide file tree
Showing 9 changed files with 516 additions and 30 deletions.
9 changes: 6 additions & 3 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 }}
Expand Down Expand Up @@ -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
Expand All @@ -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 }}
Expand Down Expand Up @@ -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
Expand All @@ -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 }}
Expand Down
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
73 changes: 73 additions & 0 deletions docs/content.en/docs/features/value.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.


68 changes: 68 additions & 0 deletions docs/content.ja/docs/features/value.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`にならないため、エラーとして検出できます。

5 changes: 5 additions & 0 deletions include/toml11/parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}

Expand Down
Loading

0 comments on commit f64ef36

Please sign in to comment.