Skip to content

Commit 394c55a

Browse files
committed
refactor(metadata): integrate Boost.Describe to remove manual mapping boilerplate
This introduces Boost.Describe and Boost.Mp11 and applies them across metadata types (symbols, enums, inline elements) to replace hand-written io.map() calls with reflection-based code. This improves maintainability without altering the public API or user-facing features.
1 parent c3dbded commit 394c55a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+675
-295
lines changed

.github/workflows/ci.yml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,36 @@ jobs:
432432
run: |
433433
rm -r ../third-party/llvm-project
434434
435+
- name: Install Boost.Describe
436+
uses: alandefreitas/cpp-actions/cmake-workflow@v1.8.12
437+
with:
438+
source-dir: build/third-party/source/boost_describe
439+
git-repository: https://github.com/boostorg/describe
440+
git-tag: boost-1.89.0
441+
build-dir: ${sourceDir}/build
442+
cc: ${{ steps.setup-cpp.outputs.cc }}
443+
cxx: ${{ steps.setup-cpp.outputs.cxx }}
444+
build-type: Release
445+
shared: false
446+
install: false
447+
run-tests: false
448+
trace-commands: true
449+
450+
- name: Install Boost.Mp11
451+
uses: alandefreitas/cpp-actions/cmake-workflow@v1.8.12
452+
with:
453+
source-dir: build/third-party/source/boost_mp11
454+
git-repository: https://github.com/boostorg/mp11
455+
git-tag: boost-1.89.0
456+
build-dir: ${sourceDir}/build
457+
cc: ${{ steps.setup-cpp.outputs.cc }}
458+
cxx: ${{ steps.setup-cpp.outputs.cxx }}
459+
build-type: Release
460+
shared: false
461+
install: false
462+
run-tests: false
463+
trace-commands: true
464+
435465
- name: Install Duktape
436466
uses: alandefreitas/cpp-actions/cmake-workflow@v1.8.12
437467
with:

CMakeLists.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,20 @@ else()
171171
)
172172
endif()
173173

174+
# Boost.Describe + Boost.Mp11 (header-only, fetched via bootstrap.py recipes)
175+
set(BOOST_DESCRIBE_ROOT "${CMAKE_SOURCE_DIR}/build/third-party/source/boost_describe")
176+
set(BOOST_MP11_ROOT "${CMAKE_SOURCE_DIR}/build/third-party/source/boost_mp11")
177+
178+
add_library(boost_mp11 INTERFACE)
179+
target_include_directories(boost_mp11 INTERFACE "${BOOST_MP11_ROOT}/include")
180+
181+
add_library(boost_describe INTERFACE)
182+
target_include_directories(boost_describe INTERFACE "${BOOST_DESCRIBE_ROOT}/include")
183+
target_link_libraries(boost_describe INTERFACE boost_mp11)
184+
set_target_properties(boost_describe boost_mp11 PROPERTIES
185+
EXPORT_NAME ""
186+
)
187+
174188
#-------------------------------------------------
175189
#
176190
# Docs build
@@ -208,6 +222,8 @@ if (MRDOCS_DOCUMENTATION_BUILD)
208222
"${BIN_INCLUDE_DIR}"
209223
)
210224

225+
target_link_libraries(mrdocs-documentation-build PRIVATE boost_describe boost_mp11)
226+
211227
# Other defines so headers compile standalone
212228
target_compile_definitions(mrdocs-documentation-build PRIVATE MRDOCS_STATIC_LINK)
213229

@@ -322,6 +338,8 @@ target_include_directories(mrdocs-core
322338
PUBLIC
323339
"$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include/>"
324340
"$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include/>"
341+
"$<BUILD_INTERFACE:${BOOST_DESCRIBE_ROOT}/include>"
342+
"$<BUILD_INTERFACE:${BOOST_MP11_ROOT}/include>"
325343
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
326344
PRIVATE
327345
"${PROJECT_SOURCE_DIR}/src"

docs/mrdocs.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@ implementation-defined:
1313
- 'mrdocs::detail'
1414
- 'mrdocs::report::detail'
1515
- 'mrdocs::dom::detail'
16+
exclude-symbols:
17+
- 'boost_base_descriptor_fn'
18+
- 'boost_public_member_descriptor_fn'
19+
- 'boost_protected_member_descriptor_fn'
20+
- 'boost_private_member_descriptor_fn'
21+
- 'boost_enum_descriptor_fn'
22+
- 'should_use_BOOST_DESCRIBE_NESTED_ENUM'
1623
multipage: true
1724
generator: adoc
1825
cmake: '-D MRDOCS_DOCUMENTATION_BUILD=ON'

include/mrdocs/Dom/LazyArray.hpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
55
//
66
// Copyright (c) 2024 Alan de Freitas (alandefreitas@gmail.com)
7+
// Copyright (c) 2025 Gennaro Prota (gennaro.prota@gmail.com)
78
//
89
// Official repository: https://github.com/cppalliance/mrdocs
910
//
@@ -211,6 +212,26 @@ TransformArray(T const& arr, F const& f)
211212
}
212213

213214
} // dom
215+
216+
class DomCorpus;
217+
218+
/** Map a vector of strings to a @ref dom::Value object.
219+
220+
@param v The output parameter to receive the dom::Value.
221+
@param elems The vector of T's to convert.
222+
@param domCorpus The DomCorpus used to resolve references.
223+
*/
224+
template <typename T>
225+
void
226+
tag_invoke(
227+
dom::ValueFromTag,
228+
dom::Value& v,
229+
std::vector<T> const& elems,
230+
DomCorpus const* domCorpus)
231+
{
232+
v = dom::LazyArray(elems, domCorpus);
233+
}
234+
214235
} // mrdocs
215236

216237

include/mrdocs/Metadata/DocComment/Inline/ImageInline.hpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,19 @@
55
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66
//
77
// Copyright (c) 2025 Alan de Freitas (alandefreitas@gmail.com)
8+
// Copyright (c) 2025 Gennaro Prota (gennaro.prota@gmail.com)
89
//
910
// Official repository: https://github.com/cppalliance/mrdocs
1011
//
1112

1213
#ifndef MRDOCS_API_METADATA_DOCCOMMENT_INLINE_IMAGEINLINE_HPP
1314
#define MRDOCS_API_METADATA_DOCCOMMENT_INLINE_IMAGEINLINE_HPP
1415

16+
#include <boost/describe/class.hpp>
1517
#include <mrdocs/Platform.hpp>
1618
#include <mrdocs/ADT/Polymorphic.hpp>
1719
#include <mrdocs/Metadata/DocComment/Inline/TextInline.hpp>
20+
#include <mrdocs/Metadata/Symbol/SymbolDescribeMapper.hpp>
1821
#include <string>
1922

2023
namespace mrdocs::doc {
@@ -52,6 +55,12 @@ struct ImageInline final
5255
bool operator==(ImageInline const&) const noexcept = default;
5356
};
5457

58+
BOOST_DESCRIBE_STRUCT(
59+
ImageInline,
60+
(InlineCommonBase<InlineKind::Image>, InlineContainer),
61+
(src, alt)
62+
)
63+
5564
/** Map the @ref ImageInline to a @ref dom::Object.
5665
5766
@param t The tag.
@@ -69,8 +78,7 @@ tag_invoke(
6978
{
7079
tag_invoke(t, io, dynamic_cast<Inline const&>(I), domCorpus);
7180
tag_invoke(t, io, dynamic_cast<InlineContainer const&>(I), domCorpus);
72-
io.map("src", I.src);
73-
io.map("alt", I.alt);
81+
mapWithDescribe(io, I, domCorpus);
7482
}
7583

7684
/** Return the @ref ImageInline as a @ref dom::Value object.

include/mrdocs/Metadata/Expression.hpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
55
//
66
// Copyright (c) 2023 Krystian Stasiowski (sdkrystian@gmail.com)
7+
// Copyright (c) 2025 Gennaro Prota (gennaro.prota@gmail.com)
78
//
89
// Official repository: https://github.com/cppalliance/mrdocs
910
//
@@ -13,12 +14,17 @@
1314

1415
#include <mrdocs/Platform.hpp>
1516
#include <mrdocs/ADT/Optional.hpp>
17+
#include <mrdocs/Dom/Array.hpp>
18+
#include <mrdocs/Dom/LazyObject.hpp>
19+
#include <mrdocs/Dom/Value.hpp>
1620
#include <concepts>
1721
#include <optional>
1822
#include <string>
1923

2024
namespace mrdocs {
2125

26+
class DomCorpus;
27+
2228
/** Represents an expression
2329
*/
2430
struct ExprInfo
@@ -90,6 +96,39 @@ static void merge(
9096
}
9197
}
9298

99+
/** Map an ExprInfo to a @ref dom::Value object.
100+
101+
@param v The output parameter to receive the dom::Value.
102+
@param expr The expression info to convert.
103+
*/
104+
inline
105+
void
106+
tag_invoke(
107+
dom::ValueFromTag,
108+
dom::Value& v,
109+
ExprInfo const& expr,
110+
DomCorpus const*)
111+
{
112+
v = expr.Written;
113+
}
114+
115+
/** Map an ExprInfo to a @ref dom::Value object.
116+
117+
@param v The output parameter to receive the dom::Value.
118+
@param expr The expression info to convert.
119+
*/
120+
inline
121+
void
122+
tag_invoke(
123+
dom::LazyObjectMapTag,
124+
dom::Value& v,
125+
ExprInfo const& expr,
126+
DomCorpus const*
127+
)
128+
{
129+
v = expr.Written;
130+
}
131+
93132
} // mrdocs
94133

95134
#endif

include/mrdocs/Metadata/Symbol/Concept.hpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,22 @@
44
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
55
//
66
// Copyright (c) 2024 Krystian Stasiowski (sdkrystian@gmail.com)
7+
// Copyright (c) 2025 Gennaro Prota (gennaro.prota@gmail.com)
78
//
89
// Official repository: https://github.com/cppalliance/mrdocs
910
//
1011

1112
#ifndef MRDOCS_API_METADATA_SYMBOL_CONCEPT_HPP
1213
#define MRDOCS_API_METADATA_SYMBOL_CONCEPT_HPP
1314

15+
#include <boost/describe/class.hpp>
1416
#include <mrdocs/Platform.hpp>
1517
#include <mrdocs/ADT/Optional.hpp>
1618
#include <mrdocs/ADT/Polymorphic.hpp>
1719
#include <mrdocs/Metadata/Expression.hpp>
1820
#include <mrdocs/Metadata/Symbol.hpp>
1921
#include <mrdocs/Metadata/Symbol/Source.hpp>
22+
#include <mrdocs/Metadata/Symbol/SymbolDescribeMapper.hpp>
2023
#include <mrdocs/Metadata/Template.hpp>
2124

2225
namespace mrdocs {
@@ -49,6 +52,12 @@ struct ConceptSymbol final
4952
operator<=>(ConceptSymbol const& other) const;
5053
};
5154

55+
BOOST_DESCRIBE_STRUCT(
56+
ConceptSymbol,
57+
(SymbolCommonBase<SymbolKind::Concept>),
58+
(Template, Constraint)
59+
)
60+
5261
/** Merge another ConceptSymbol into this one.
5362
*/
5463
MRDOCS_DECL
@@ -71,11 +80,8 @@ tag_invoke(
7180
DomCorpus const* domCorpus)
7281
{
7382
tag_invoke(t, io, I.asInfo(), domCorpus);
74-
io.map("template", I.Template);
75-
if (!I.Constraint.Written.empty())
76-
{
77-
io.map("constraint", I.Constraint.Written);
78-
}
83+
mapWithDescribe(io, I, domCorpus);
84+
7985
}
8086

8187
/** Map the ConceptSymbol to a @ref dom::Value object.

include/mrdocs/Metadata/Symbol/Enum.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,21 @@
55
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66
//
77
// Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com)
8+
// Copyright (c) 2025 Gennaro Prota (gennaro.prota@gmail.com)
89
//
910
// Official repository: https://github.com/cppalliance/mrdocs
1011
//
1112

1213
#ifndef MRDOCS_API_METADATA_SYMBOL_ENUM_HPP
1314
#define MRDOCS_API_METADATA_SYMBOL_ENUM_HPP
1415

16+
#include <boost/describe/class.hpp>
1517
#include <mrdocs/Platform.hpp>
1618
#include <mrdocs/ADT/Polymorphic.hpp>
1719
#include <mrdocs/Dom/LazyArray.hpp>
1820
#include <mrdocs/Metadata/Symbol.hpp>
1921
#include <mrdocs/Metadata/Symbol/Source.hpp>
22+
#include <mrdocs/Metadata/Symbol/SymbolDescribeMapper.hpp>
2023
#include <mrdocs/Metadata/Type.hpp>
2124

2225
namespace mrdocs {
@@ -65,6 +68,12 @@ struct EnumSymbol final
6568
}
6669
};
6770

71+
BOOST_DESCRIBE_STRUCT(
72+
EnumSymbol,
73+
(SymbolCommonBase<SymbolKind::Enum>),
74+
(Scoped, UnderlyingType, Constants)
75+
)
76+
6877
/** Return the list of enum constants for this symbol.
6978
*/
7079
inline

include/mrdocs/Metadata/Symbol/EnumConstant.hpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,18 @@
44
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
55
//
66
// Copyright (c) 2023 Krystian Stasiowski (sdkrystian@gmail.com)
7+
// Copyright (c) 2025 Gennaro Prota (gennaro.prota@gmail.com)
78
//
89
// Official repository: https://github.com/cppalliance/mrdocs
910
//
1011

1112
#ifndef MRDOCS_API_METADATA_SYMBOL_ENUMCONSTANT_HPP
1213
#define MRDOCS_API_METADATA_SYMBOL_ENUMCONSTANT_HPP
1314

15+
#include <boost/describe/class.hpp>
1416
#include <mrdocs/Metadata/Expression.hpp>
1517
#include <mrdocs/Metadata/Symbol.hpp>
18+
#include <mrdocs/Metadata/Symbol/SymbolDescribeMapper.hpp>
1619
#include <mrdocs/Metadata/Symbol/Source.hpp>
1720

1821
namespace mrdocs {
@@ -36,6 +39,12 @@ struct EnumConstantSymbol final
3639
}
3740
};
3841

42+
BOOST_DESCRIBE_STRUCT(
43+
EnumConstantSymbol,
44+
(SymbolCommonBase<SymbolKind::EnumConstant>),
45+
(Initializer)
46+
)
47+
3948
/** Merge another EnumConstantSymbol into this one.
4049
@param I Destination symbol to update.
4150
@param Other Source symbol providing data.
@@ -60,10 +69,7 @@ tag_invoke(
6069
DomCorpus const* domCorpus)
6170
{
6271
tag_invoke(t, io, I.asInfo(), domCorpus);
63-
if (!I.Initializer.Written.empty())
64-
{
65-
io.map("initializer", I.Initializer.Written);
66-
}
72+
mapWithDescribe(io, I, domCorpus);
6773
}
6874

6975
/** Map the EnumConstantSymbol to a @ref dom::Value object.

0 commit comments

Comments
 (0)