diff --git a/.github/scripts/check-cpp-docs.py b/.github/scripts/check-cpp-docs.py new file mode 100644 index 0000000..d7bca59 --- /dev/null +++ b/.github/scripts/check-cpp-docs.py @@ -0,0 +1,117 @@ +#!/usr/bin/env python3 +"""Require bilingual documentation on public C++ declarations.""" + +from pathlib import Path +import re +import sys + + +def declaration_kind(line: str) -> str | None: + stripped = line.strip() + if re.match(r"(?:struct|class)\s+\w+", stripped): + return "type" + if re.match(r"concept\s+\w+\s*=", stripped): + return "type" + if re.match(r"using\s+\w+\s*=", stripped): + return "alias" + if stripped.startswith("virtual "): + return "method" + if stripped.startswith("#define "): + return "macro" + if re.match(r"(?:THIS_REFERENCE_WRAPPER_METHODS|VARIABLE_WRAPPER_METHODS|USE_ALL_BASE_CONSTRUCTORS)\(", stripped): + return "generated members" + if re.match(r"ExtendedReferenceBase\(", stripped): + return "constructor" + if re.match(r"TExtendable&?\s+extendable;", stripped): + return "field" + return None + + +def documentation_before(lines: list[str], index: int) -> tuple[str, str]: + previous = index - 1 + template = "" + if previous >= 0 and lines[previous].strip().startswith("template <"): + template = lines[previous].strip() + previous -= 1 + comment = [] + while previous >= 0 and lines[previous].lstrip().startswith("///"): + comment.append(lines[previous].strip()) + previous -= 1 + return "\n".join(reversed(comment)), template + + +def summary_errors(comment: str, label: str) -> list[str]: + errors = [] + if "" not in comment or "" not in comment: + return [f"{label} lacks a documentation summary"] + paragraphs = re.findall(r"(.*?)", comment) + if not any(re.search(r"[A-Za-z]", paragraph) for paragraph in paragraphs) or not any( + re.search(r"[А-Яа-яЁё]", paragraph) for paragraph in paragraphs + ): + errors.append(f"{label} lacks English and Russian paragraphs") + return errors + + +def template_errors(comment: str, template: str, label: str) -> list[str]: + parameters = dict.fromkeys(re.findall(r"\bT(?:[A-Z]\w*)?\b", template)) + return [ + f"{label} lacks documentation for {parameter}" + for parameter in parameters + if f'' not in comment + ] + + +def callable_errors(comment: str, signature: str, kind: str, label: str) -> list[str]: + errors = [] + arguments = re.search(r"\((.*?)\)", signature) + if arguments: + for argument in arguments.group(1).split(","): + name = re.search(r"(\w+)$", argument.strip()) + if name and f'' not in comment: + errors.append(f"{label} lacks documentation for argument {name.group(1)}") + if kind == "method" and not ("virtual void " in signature or "virtual ~" in signature) and "" not in comment: + errors.append(f"{label} lacks return documentation") + return errors + + +def declaration_errors(lines: list[str], index: int, kind: str, path: Path) -> list[str]: + comment, template = documentation_before(lines, index) + label = f"{path}:{index + 1}: {kind}" + errors = summary_errors(comment, label) + if kind == "type": + errors.extend(template_errors(comment, template, label)) + if kind in {"method", "constructor"}: + errors.extend(callable_errors(comment, lines[index].strip(), kind, label)) + return errors + + +def validate_header(path: Path) -> list[str]: + lines = path.read_text(encoding="utf-8-sig").splitlines() + errors = [] + inside_internal = False + for index, line in enumerate(lines): + if "namespace Internal {" in line: + inside_internal = True + if "} // namespace Internal" in line: + inside_internal = False + continue + if inside_internal: + continue + kind = declaration_kind(line) + if kind is not None: + errors.extend(declaration_errors(lines, index, kind, path)) + return errors + + +def main() -> int: + root = Path(__file__).resolve().parents[2] / "cpp" / "Platform.Interfaces" + errors = [error for path in sorted(root.glob("*.h")) for error in validate_header(path)] + if errors: + print("\n".join(errors), file=sys.stderr) + return 1 + print(f"Bilingual documentation covers the public declarations in {len(list(root.glob('*.h')))} C++ headers.") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/.github/scripts/check-cpp-docs.test.py b/.github/scripts/check-cpp-docs.test.py new file mode 100644 index 0000000..ec6a6a5 --- /dev/null +++ b/.github/scripts/check-cpp-docs.test.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python3 +"""Regression checks for C++ documentation coverage.""" + +from importlib.util import module_from_spec, spec_from_file_location +from pathlib import Path +from tempfile import TemporaryDirectory +import unittest + + +script = Path(__file__).with_name("check-cpp-docs.py") +spec = spec_from_file_location("check_cpp_docs", script) +module = module_from_spec(spec) +spec.loader.exec_module(module) + + +class DocumentationCoverageTests(unittest.TestCase): + def validate(self, source: str) -> list[str]: + with TemporaryDirectory() as directory: + path = Path(directory) / "Test.h" + path.write_text(source) + return module.validate_header(path) + + def test_undocumented_concept_is_rejected(self): + self.assertTrue(self.validate("template \nconcept CExample = true;\n")) + + def test_undocumented_primary_template_is_rejected(self): + self.assertTrue(self.validate("template \nstruct IExample;\n")) + + def test_bilingual_concept_with_type_parameter_is_accepted(self): + source = """/// +/// Checks an example. +/// Проверяет пример. +/// +/// The type. +template +concept CExample = true; +""" + self.assertEqual(self.validate(source), []) + + def test_undocumented_public_member_is_rejected(self): + source = """/// +/// A holder. +/// Хранилище. +/// +struct Holder { + using Value = int; +}; +""" + self.assertTrue(any("alias" in error for error in self.validate(source))) + + +if __name__ == "__main__": + unittest.main() diff --git a/.github/scripts/check-csharp-docs.py b/.github/scripts/check-csharp-docs.py new file mode 100644 index 0000000..d3d1dea --- /dev/null +++ b/.github/scripts/check-csharp-docs.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python3 +"""Require English and Russian paragraphs in generated C# API documentation.""" + +from pathlib import Path +import re +import sys +import xml.etree.ElementTree as ET + + +DOCUMENTATION_TAGS = {"summary", "remarks", "typeparam", "param", "returns", "value", "example", "exception"} + + +def has_bilingual_paragraphs(element: ET.Element) -> bool: + paragraphs = ["".join(paragraph.itertext()) for paragraph in element.findall("para")] + return any(re.search(r"[A-Za-z]", paragraph) for paragraph in paragraphs) and any( + re.search(r"[А-Яа-яЁё]", paragraph) for paragraph in paragraphs + ) + + +def validate_xml(path: Path) -> list[str]: + root = ET.parse(path).getroot() + members = root.findall("./members/member") + if not members: + return [f"{path}: generated XML contains no documented API members"] + + errors = [] + for member in members: + name = member.get("name", "unnamed member") + if member.find("summary") is None: + errors.append(f"{name}: missing summary") + for section in member: + if section.tag not in DOCUMENTATION_TAGS: + continue + label = f"{section.tag} {section.get('name', '')}".strip() + if not has_bilingual_paragraphs(section): + errors.append(f"{name}: {label} lacks English and Russian paragraphs") + return errors + + +def main() -> int: + if len(sys.argv) != 2: + print("Usage: check-csharp-docs.py XML_FILE", file=sys.stderr) + return 2 + path = Path(sys.argv[1]) + try: + errors = validate_xml(path) + except (OSError, ET.ParseError) as error: + print(f"{path}: {error}", file=sys.stderr) + return 1 + if errors: + print("\n".join(errors), file=sys.stderr) + return 1 + count = len(ET.parse(path).getroot().findall("./members/member")) + print(f"Validated bilingual XML documentation for {count} C# API members.") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/.github/scripts/check-csharp-docs.test.py b/.github/scripts/check-csharp-docs.test.py new file mode 100644 index 0000000..1fe527e --- /dev/null +++ b/.github/scripts/check-csharp-docs.test.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python3 +"""Regression checks for generated C# XML documentation.""" + +from importlib.util import module_from_spec, spec_from_file_location +from pathlib import Path +from tempfile import TemporaryDirectory +import unittest + + +script = Path(__file__).with_name("check-csharp-docs.py") +spec = spec_from_file_location("check_csharp_docs", script) +module = module_from_spec(spec) +spec.loader.exec_module(module) + + +class DocumentationCoverageTests(unittest.TestCase): + def validate(self, content: str) -> list[str]: + with TemporaryDirectory() as directory: + path = Path(directory) / "Platform.Interfaces.xml" + path.write_text(content, encoding="utf-8") + return module.validate_xml(path) + + def test_bilingual_member_and_parameter_are_accepted(self): + xml = """ + Runs.Запускает. + Input.Ввод. + """ + self.assertEqual(self.validate(xml), []) + + def test_missing_russian_summary_is_rejected(self): + xml = """ + An example. + """ + self.assertTrue(any("summary" in error for error in self.validate(xml))) + + def test_missing_english_parameter_is_rejected(self): + xml = """ + Runs.Запускает. + Ввод. + """ + self.assertTrue(any("param input" in error for error in self.validate(xml))) + + def test_empty_member_list_is_rejected(self): + self.assertTrue(self.validate("")) + + +if __name__ == "__main__": + unittest.main() diff --git a/.github/scripts/validate-csharp-package.sh b/.github/scripts/validate-csharp-package.sh index 4255424..9f08283 100755 --- a/.github/scripts/validate-csharp-package.sh +++ b/.github/scripts/validate-csharp-package.sh @@ -33,7 +33,7 @@ if [[ ${#symbol_packages[@]} -ne 0 ]]; then fi package_contents=$(unzip -Z1 "${packages[0]}") -for expected_file in README.md icon.png lib/net8.0/Platform.Interfaces.dll; do +for expected_file in README.md icon.png lib/net8.0/Platform.Interfaces.dll lib/net8.0/Platform.Interfaces.xml; do if ! grep -Fxq "$expected_file" <<< "$package_contents"; then echo "${packages[0]} is missing $expected_file." >&2 exit 1 diff --git a/.github/workflows/cpp-docs.yml b/.github/workflows/cpp-docs.yml new file mode 100644 index 0000000..904d835 --- /dev/null +++ b/.github/workflows/cpp-docs.yml @@ -0,0 +1,50 @@ +name: C++ documentation + +on: + push: + branches: [main] + paths: + - 'cpp/Platform.Interfaces/**' + - 'cpp/Doxyfile' + - '.github/scripts/check-cpp-docs.py' + - '.github/scripts/check-cpp-docs.test.py' + - '.github/workflows/cpp-docs.yml' + pull_request: + branches: [main] + paths: + - 'cpp/Platform.Interfaces/**' + - 'cpp/Doxyfile' + - '.github/scripts/check-cpp-docs.py' + - '.github/scripts/check-cpp-docs.test.py' + - '.github/workflows/cpp-docs.yml' + +jobs: + build: + runs-on: ubuntu-24.04 + timeout-minutes: 10 + permissions: + contents: read + steps: + - uses: actions/checkout@v7 + with: + persist-credentials: false + - name: Install Doxygen + run: | + sudo apt-get update + sudo apt-get install -y doxygen + - name: Check documentation coverage + run: | + python3 .github/scripts/check-cpp-docs.test.py + python3 .github/scripts/check-cpp-docs.py + - name: Generate documentation + run: | + doxygen cpp/Doxyfile + test -s cpp/docs/html/index.html + test -s cpp/docs/xml/index.xml + - name: Upload HTML and XML documentation + uses: actions/upload-artifact@v4 + with: + name: cpp-api-documentation + path: | + cpp/docs/html + cpp/docs/xml diff --git a/.github/workflows/csharp.yml b/.github/workflows/csharp.yml index 4ade993..b4597cc 100644 --- a/.github/workflows/csharp.yml +++ b/.github/workflows/csharp.yml @@ -47,6 +47,11 @@ jobs: - name: Validate tests and NuGet package run: ../.github/scripts/validate-csharp-package.sh + - name: Validate bilingual C# API documentation + run: | + python3 ../.github/scripts/check-csharp-docs.test.py + python3 ../.github/scripts/check-csharp-docs.py Platform.Interfaces/bin/Release/net8/Platform.Interfaces.xml + - name: Test C# workflow safeguards run: node --test ../.github/scripts/*csharp*.test.mjs diff --git a/.gitignore b/.gitignore index c489eb5..8b3ea17 100644 --- a/.gitignore +++ b/.gitignore @@ -326,6 +326,9 @@ ASALocalRun/ # Generated DocFX site csharp/_site/ +# Generated Doxygen site +cpp/docs/ + # NVidia Nsight GPU debugger configuration file *.nvuser diff --git a/README.md b/README.md index 066ef74..34accc9 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,9 @@ NuGet package: [Platform.Interfaces](https://www.nuget.org/packages/Platform.Int [PDF file](https://linksplatform.github.io/Interfaces/csharp/Platform.Interfaces.pdf) with code for e-readers. -[API documentation PDF](https://linksplatform.github.io/Interfaces/csharp/Platform.Interfaces.Documentation.pdf) generated by DocFX. +The [C++ documentation workflow](https://github.com/linksplatform/Interfaces/actions/workflows/cpp-docs.yml) checks bilingual English/Russian comments and generates an HTML and XML API reference as a downloadable artifact. Run `doxygen cpp/Doxyfile` from the repository root to build it locally. + +The [C# workflow](https://github.com/linksplatform/Interfaces/actions/workflows/csharp.yml) checks bilingual XML comments and publishes the DocFX site, including the [API documentation PDF](https://linksplatform.github.io/Interfaces/csharp/Platform.Interfaces.Documentation.pdf). ## Dependent libraries * [Platform.Collections](https://github.com/linksplatform/Collections) diff --git a/cpp/Doxyfile b/cpp/Doxyfile new file mode 100644 index 0000000..da8a1e3 --- /dev/null +++ b/cpp/Doxyfile @@ -0,0 +1,27 @@ +PROJECT_NAME = "Platform.Interfaces C++" +# Run from the repository root. The output is ignored locally and uploaded by CI. +OUTPUT_DIRECTORY = cpp/docs +INPUT = cpp/Platform.Interfaces +FILE_PATTERNS = *.h +RECURSIVE = NO +GENERATE_HTML = YES +GENERATE_LATEX = NO +GENERATE_XML = YES +HAVE_DOT = NO +EXTRACT_ALL = NO +EXTRACT_PRIVATE = NO +EXTRACT_STATIC = NO +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_AS_ERROR = FAIL_ON_WARNINGS +QUIET = YES +EXCLUDE_SYMBOLS = Platform::Interfaces::Internal +MACRO_EXPANSION = YES +EXPAND_ONLY_PREDEF = YES +# These replacements let Doxygen parse template bases and macro-generated methods. +# The original declarations remain unchanged in the published headers. +PREDEFINED = "THIS_REFERENCE_WRAPPER_METHODS(x,y)=" \ + "VARIABLE_WRAPPER_METHODS(x,y)=" \ + "USE_ALL_BASE_CONSTRUCTORS(x,y)=" \ + "EXTENDED_BASE_TYPE(a,b,c,d,e)=c" \ + "DECORATED_BASE_TYPE(a,b,c,d,e)=c" diff --git a/cpp/Platform.Interfaces/CArray.h b/cpp/Platform.Interfaces/CArray.h index fa68e64..a99ff80 100644 --- a/cpp/Platform.Interfaces/CArray.h +++ b/cpp/Platform.Interfaces/CArray.h @@ -29,9 +29,29 @@ namespace Platform::Interfaces { } } // namespace Internal + /// + /// Requires an enumerable with indexed random access and, optionally, a specified item type. + /// Требует перечисляемую коллекцию с произвольным доступом по индексу и, при необходимости, заданным типом элемента. + /// + /// + /// The type checked by this concept or described by this helper. + /// Тип, проверяемый этим концептом или описываемый этим вспомогательным типом. + /// + /// + /// Optional item types. + /// Необязательные типы элементов. + /// template concept CArray = CEnumerable && Internal::CArrayHelpFunction(); + /// + /// Exposes the item and iterator types of an array. + /// Предоставляет типы элементов и итератора массива. + /// + /// + /// The type checked by this concept or described by this helper. + /// Тип, проверяемый этим концептом или описываемый этим вспомогательным типом. + /// template struct Array : Enumerable {}; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/CCli.h b/cpp/Platform.Interfaces/CCli.h index 2843a8c..f5c599a 100644 --- a/cpp/Platform.Interfaces/CCli.h +++ b/cpp/Platform.Interfaces/CCli.h @@ -5,8 +5,16 @@ #include namespace Platform::Interfaces { + /// + /// Requires a command runner that returns an exit code. + /// Требует исполнитель команды, возвращающий код завершения. + /// + /// + /// The type checked by this concept or described by this helper. + /// Тип, проверяемый этим концептом или описываемый этим вспомогательным типом. + /// template concept CCli = requires(TSelf self, const std::vector& args) { { self.Run(args) } -> std::same_as; }; -} // namespace Platform::Interfaces \ No newline at end of file +} // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/CCounter.h b/cpp/Platform.Interfaces/CCounter.h index 587ab24..d6d124a 100644 --- a/cpp/Platform.Interfaces/CCounter.h +++ b/cpp/Platform.Interfaces/CCounter.h @@ -3,6 +3,22 @@ #include namespace Platform::Interfaces { + /// + /// Requires a counter returning the specified result, with at most one argument. + /// Требует счётчик, возвращающий заданный результат и принимающий не более одного аргумента. + /// + /// + /// The type checked by this concept or described by this helper. + /// Тип, проверяемый этим концептом или описываемый этим вспомогательным типом. + /// + /// + /// The result type. + /// Тип результата. + /// + /// + /// Optional argument type. + /// Необязательный тип аргумента. + /// template concept CCounter = sizeof...(TArgument) <= 1 && requires(TSelf self, TArgument... argument) { { self.Count(argument...) } -> std::same_as; diff --git a/cpp/Platform.Interfaces/CDictionary.h b/cpp/Platform.Interfaces/CDictionary.h index 25f8cff..a72be95 100644 --- a/cpp/Platform.Interfaces/CDictionary.h +++ b/cpp/Platform.Interfaces/CDictionary.h @@ -108,23 +108,87 @@ namespace Platform::Interfaces { } } // namespace Internal + /// + /// Requires a mutable enumerable dictionary with lookup, insertion and removal operations. + /// Требует изменяемый перечисляемый словарь с поиском, вставкой и удалением. + /// + /// + /// The type checked by this concept or described by this helper. + /// Тип, проверяемый этим концептом или описываемый этим вспомогательным типом. + /// + /// + /// Optional key and value types. + /// Необязательные типы ключа и значения. + /// template concept CDictionary = CEnumerable && Internal::CDictionaryHelpFunction(); + /// + /// Requires a read-only enumerable dictionary with lookup operations. + /// Требует доступный только для чтения перечисляемый словарь с операциями поиска. + /// + /// + /// The type checked by this concept or described by this helper. + /// Тип, проверяемый этим концептом или описываемый этим вспомогательным типом. + /// + /// + /// Optional key and value types. + /// Необязательные типы ключа и значения. + /// template concept CReadonlyDictionary = CEnumerable && Internal::CReadonlyDictionaryHelpFunction(); + /// + /// Exposes the item, key and value types of a mutable dictionary. + /// Предоставляет типы элемента, ключа и значения изменяемого словаря. + /// + /// + /// The type checked by this concept or described by this helper. + /// Тип, проверяемый этим концептом или описываемый этим вспомогательным типом. + /// template struct Dictionary : Enumerable { + /// + /// The enumerable base type. + /// Базовый перечисляемый тип. + /// using base = Enumerable; + /// + /// The key type. + /// Тип ключа. + /// using Key = decltype(std::get<0>(std::declval())); + /// + /// The value type. + /// Тип значения. + /// using Value = decltype(std::get<1>(std::declval())); }; + /// + /// Exposes the item, key and value types of a read-only dictionary. + /// Предоставляет типы элемента, ключа и значения словаря, доступного только для чтения. + /// + /// + /// The type checked by this concept or described by this helper. + /// Тип, проверяемый этим концептом или описываемый этим вспомогательным типом. + /// template struct ReadonlyDictionary : Enumerable { + /// + /// The enumerable base type. + /// Базовый перечисляемый тип. + /// using base = Enumerable; + /// + /// The key type. + /// Тип ключа. + /// using Key = decltype(std::get<0>(std::declval())); + /// + /// The value type. + /// Тип значения. + /// using Value = decltype(std::get<1>(std::declval())); }; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/CEnumerable.h b/cpp/Platform.Interfaces/CEnumerable.h index 66659ed..2095d96 100644 --- a/cpp/Platform.Interfaces/CEnumerable.h +++ b/cpp/Platform.Interfaces/CEnumerable.h @@ -3,13 +3,41 @@ #include namespace Platform::Interfaces { + /// + /// Requires a type that can be iterated as a range. + /// Требует тип, который можно перебирать как диапазон. + /// + /// + /// The type checked by this concept or described by this helper. + /// Тип, проверяемый этим концептом или описываемый этим вспомогательным типом. + /// template concept CEnumerable = std::ranges::range; + /// + /// Exposes the item, reference and iterator types of an enumerable. + /// Предоставляет типы элемента, ссылки и итератора перечисляемого объекта. + /// + /// + /// The type checked by this concept or described by this helper. + /// Тип, проверяемый этим концептом или описываемый этим вспомогательным типом. + /// template struct Enumerable { + /// + /// The item value type. + /// Тип значения элемента. + /// using Item = std::ranges::range_value_t; + /// + /// The item reference type. + /// Тип ссылки на элемент. + /// using ItemReference = std::ranges::range_reference_t; + /// + /// The iterator type. + /// Тип итератора. + /// using Iter = std::ranges::iterator_t; }; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/CFactory.h b/cpp/Platform.Interfaces/CFactory.h index fee54c7..726caf7 100644 --- a/cpp/Platform.Interfaces/CFactory.h +++ b/cpp/Platform.Interfaces/CFactory.h @@ -3,6 +3,18 @@ #include namespace Platform::Interfaces { + /// + /// Requires a factory that creates the specified product type. + /// Требует фабрику, создающую объект заданного типа. + /// + /// + /// The type checked by this concept or described by this helper. + /// Тип, проверяемый этим концептом или описываемый этим вспомогательным типом. + /// + /// + /// The type of the created product. + /// Тип создаваемого объекта. + /// template concept CFactory = requires(TSelf self) { { self.Create() } -> std::same_as; diff --git a/cpp/Platform.Interfaces/CLink.h b/cpp/Platform.Interfaces/CLink.h index 5f0671c..9951e3c 100644 --- a/cpp/Platform.Interfaces/CLink.h +++ b/cpp/Platform.Interfaces/CLink.h @@ -4,6 +4,14 @@ #include namespace Platform::Interfaces { + /// + /// Requires a link with endpoints, a value type and an empty-state query. + /// Требует связь с концами, типом значения и проверкой пустого состояния. + /// + /// + /// The type checked by this concept or described by this helper. + /// Тип, проверяемый этим концептом или описываемый этим вспомогательным типом. + /// template concept CLink = requires(TSelf self) { { self.empty() } -> std::same_as; @@ -12,8 +20,20 @@ namespace Platform::Interfaces { { self.end } -> std::same_as; }; + /// + /// Exposes the value type of a link. + /// Предоставляет тип значения связи. + /// + /// + /// The type checked by this concept or described by this helper. + /// Тип, проверяемый этим концептом или описываемый этим вспомогательным типом. + /// template struct Link { + /// + /// The value type of the link. + /// Тип значения связи. + /// using value_type = typename TSelf::value_type; }; -} // namespace Platform::Interfaces \ No newline at end of file +} // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/CLinkAddress.h b/cpp/Platform.Interfaces/CLinkAddress.h index e9624f1..1b8cdf2 100644 --- a/cpp/Platform.Interfaces/CLinkAddress.h +++ b/cpp/Platform.Interfaces/CLinkAddress.h @@ -4,6 +4,14 @@ #include namespace Platform::Interfaces { + /// + /// Requires an unsigned integral link address. + /// Требует беззнаковый целочисленный адрес связи. + /// + /// + /// The type checked as a link address. + /// Тип, проверяемый как адрес связи. + /// template concept CLinkAddress = std::is_integral::value && std::is_unsigned::value; } diff --git a/cpp/Platform.Interfaces/CLinks.h b/cpp/Platform.Interfaces/CLinks.h index 3d76aeb..f55173f 100644 --- a/cpp/Platform.Interfaces/CLinks.h +++ b/cpp/Platform.Interfaces/CLinks.h @@ -3,6 +3,14 @@ #include namespace Platform::Interfaces { + /// + /// Requires link storage with counting, enumeration, creation, update and deletion operations. + /// Требует хранилище связей с подсчётом, перебором, созданием, изменением и удалением. + /// + /// + /// The type checked by this concept or described by this helper. + /// Тип, проверяемый этим концептом или описываемый этим вспомогательным типом. + /// template concept CLinks = requires { typename TSelf::OptionsType; @@ -18,4 +26,4 @@ namespace Platform::Interfaces { { self.Update(restriction, substitution, writeHandler) } -> std::same_as; { self.Delete(restriction, writeHandler) } -> std::same_as; }; -} // namespace Platform::Interfaces \ No newline at end of file +} // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/CList.h b/cpp/Platform.Interfaces/CList.h index b1dfb6c..6e38f6c 100644 --- a/cpp/Platform.Interfaces/CList.h +++ b/cpp/Platform.Interfaces/CList.h @@ -68,15 +68,55 @@ namespace Platform::Interfaces { } } // namespace Internal + /// + /// Requires an indexed mutable list with insertion and removal operations. + /// Требует индексируемый изменяемый список с операциями вставки и удаления. + /// + /// + /// The type checked by this concept or described by this helper. + /// Тип, проверяемый этим концептом или описываемый этим вспомогательным типом. + /// + /// + /// Optional item types. + /// Необязательные типы элементов. + /// template concept CList = CArray && Internal::CListHelpFunction(); + /// + /// Requires an indexed read-only list with size and empty-state queries. + /// Требует индексируемый список только для чтения с запросами размера и пустого состояния. + /// + /// + /// The type checked by this concept or described by this helper. + /// Тип, проверяемый этим концептом или описываемый этим вспомогательным типом. + /// + /// + /// Optional item types. + /// Необязательные типы элементов. + /// template concept CReadonlyList = CArray && Internal::CReadonlyListHelpFunction(); + /// + /// Exposes the item and iterator types of a mutable list. + /// Предоставляет типы элемента и итератора изменяемого списка. + /// + /// + /// The type checked by this concept or described by this helper. + /// Тип, проверяемый этим концептом или описываемый этим вспомогательным типом. + /// template struct List : Enumerable {}; + /// + /// Exposes the item and iterator types of a read-only list. + /// Предоставляет типы элемента и итератора списка только для чтения. + /// + /// + /// The type checked by this concept or described by this helper. + /// Тип, проверяемый этим концептом или описываемый этим вспомогательным типом. + /// template struct ReadonlyList : Enumerable {}; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/CMatcher.h b/cpp/Platform.Interfaces/CMatcher.h index 66f8b22..aff3787 100644 --- a/cpp/Platform.Interfaces/CMatcher.h +++ b/cpp/Platform.Interfaces/CMatcher.h @@ -3,6 +3,18 @@ #include namespace Platform::Interfaces { + /// + /// Requires a matcher that reports whether a candidate satisfies its rule. + /// Требует объект, сообщающий, соответствует ли кандидат правилу сопоставления. + /// + /// + /// The type checked by this concept or described by this helper. + /// Тип, проверяемый этим концептом или описываемый этим вспомогательным типом. + /// + /// + /// The type of the candidate to match. + /// Тип проверяемого кандидата. + /// template concept CMatcher = requires(TSelf self, TCandidate candidate) { { self.IsMatched(candidate) } -> std::same_as; diff --git a/cpp/Platform.Interfaces/CProperties.h b/cpp/Platform.Interfaces/CProperties.h index 15fb825..fd94c3b 100644 --- a/cpp/Platform.Interfaces/CProperties.h +++ b/cpp/Platform.Interfaces/CProperties.h @@ -3,6 +3,26 @@ #include namespace Platform::Interfaces { + /// + /// Requires an operator that gets and sets a named property of an object. + /// Требует оператор, получающий и устанавливающий указанное свойство объекта. + /// + /// + /// The type checked by this concept or described by this helper. + /// Тип, проверяемый этим концептом или описываемый этим вспомогательным типом. + /// + /// + /// The object type. + /// Тип объекта. + /// + /// + /// The property reference type. + /// Тип ссылки на свойство. + /// + /// + /// The value type. + /// Тип значения. + /// template concept CProperties = requires(TSelf self, TObject& object, TProperty property, TValue value) { { self.GetValue(object, property) } -> std::same_as; diff --git a/cpp/Platform.Interfaces/CProperty.h b/cpp/Platform.Interfaces/CProperty.h index 532058e..a13c17a 100644 --- a/cpp/Platform.Interfaces/CProperty.h +++ b/cpp/Platform.Interfaces/CProperty.h @@ -4,6 +4,22 @@ #include "CSetter.h" namespace Platform::Interfaces { + /// + /// Requires an operator that gets and sets one property of an object. + /// Требует оператор, получающий и устанавливающий одно свойство объекта. + /// + /// + /// The type checked by this concept or described by this helper. + /// Тип, проверяемый этим концептом или описываемый этим вспомогательным типом. + /// + /// + /// The object type. + /// Тип объекта. + /// + /// + /// The value type. + /// Тип значения. + /// template concept CProperty = CSetter && CProvider; } diff --git a/cpp/Platform.Interfaces/CProvider.h b/cpp/Platform.Interfaces/CProvider.h index a68711f..678dfcf 100644 --- a/cpp/Platform.Interfaces/CProvider.h +++ b/cpp/Platform.Interfaces/CProvider.h @@ -3,6 +3,22 @@ #include namespace Platform::Interfaces { + /// + /// Requires a provider of the specified type with at most one argument. + /// Требует поставщика заданного типа, принимающего не более одного аргумента. + /// + /// + /// The type checked by this concept or described by this helper. + /// Тип, проверяемый этим концептом или описываемый этим вспомогательным типом. + /// + /// + /// The provided type. + /// Предоставляемый тип. + /// + /// + /// Optional argument type. + /// Необязательный тип аргумента. + /// template concept CProvider = sizeof...(TArgument) <= 1 && requires(TSelf self, TArgument... argument) { { self.Get(argument...) } -> std::same_as; diff --git a/cpp/Platform.Interfaces/CSet.h b/cpp/Platform.Interfaces/CSet.h index b61e436..d1f2bce 100644 --- a/cpp/Platform.Interfaces/CSet.h +++ b/cpp/Platform.Interfaces/CSet.h @@ -73,15 +73,55 @@ namespace Platform::Interfaces { } // namespace Internal + /// + /// Requires a mutable enumerable set with lookup, insertion and removal operations. + /// Требует изменяемое перечисляемое множество с поиском, вставкой и удалением. + /// + /// + /// The type checked by this concept or described by this helper. + /// Тип, проверяемый этим концептом или описываемый этим вспомогательным типом. + /// + /// + /// Optional item types. + /// Необязательные типы элементов. + /// template concept CSet = CEnumerable && Internal::CSetHelpFunction(); + /// + /// Requires a read-only enumerable set with lookup operations. + /// Требует доступное только для чтения перечисляемое множество с поиском. + /// + /// + /// The type checked by this concept or described by this helper. + /// Тип, проверяемый этим концептом или описываемый этим вспомогательным типом. + /// + /// + /// Optional item types. + /// Необязательные типы элементов. + /// template concept CReadonlySet = CEnumerable && Internal::CReadonlySetHelpFunction(); + /// + /// Exposes the item and iterator types of a mutable set. + /// Предоставляет типы элемента и итератора изменяемого множества. + /// + /// + /// The type checked by this concept or described by this helper. + /// Тип, проверяемый этим концептом или описываемый этим вспомогательным типом. + /// template struct Set : Enumerable {}; + /// + /// Exposes the item and iterator types of a read-only set. + /// Предоставляет типы элемента и итератора множества только для чтения. + /// + /// + /// The type checked by this concept or described by this helper. + /// Тип, проверяемый этим концептом или описываемый этим вспомогательным типом. + /// template struct ReadonlySet : Enumerable {}; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/CSetter.h b/cpp/Platform.Interfaces/CSetter.h index 72125d1..2b3c2f4 100644 --- a/cpp/Platform.Interfaces/CSetter.h +++ b/cpp/Platform.Interfaces/CSetter.h @@ -3,6 +3,22 @@ #include namespace Platform::Interfaces { + /// + /// Requires a setter that accepts a value and at most one additional argument. + /// Требует установщик, принимающий значение и не более одного дополнительного аргумента. + /// + /// + /// The type checked by this concept or described by this helper. + /// Тип, проверяемый этим концептом или описываемый этим вспомогательным типом. + /// + /// + /// The value type. + /// Тип значения. + /// + /// + /// Optional argument type. + /// Необязательный тип аргумента. + /// template concept CSetter = sizeof...(TArgument) <= 1 && requires(TSelf self, TArgument... argument, TValue value) { { self.Set(argument..., value) } -> std::same_as; diff --git a/cpp/Platform.Interfaces/Decorated.h b/cpp/Platform.Interfaces/Decorated.h index 773448f..a053042 100644 --- a/cpp/Platform.Interfaces/Decorated.h +++ b/cpp/Platform.Interfaces/Decorated.h @@ -3,10 +3,34 @@ #include "Macros.h" namespace Platform::Interfaces { + /// + /// Composes one or more decorators around an object. + /// Объединяет один или несколько декораторов вокруг объекта. + /// + /// + /// The decorated object type. + /// Тип декорируемого объекта. + /// + /// + /// The first decorator template. + /// Шаблон первого декоратора. + /// + /// + /// The remaining decorator templates. + /// Шаблоны остальных декораторов. + /// template typename TFirstDecorator, template typename... TDecorators> struct Decorated : public DecoratedBase, TDecorated, TFirstDecorator, TDecorators...> { + /// + /// The composed decorator base type. + /// Тип базовой цепочки декораторов. + /// using base = DecoratedBase, TDecorated, TFirstDecorator, TDecorators...>; + /// + /// Forwards constructor arguments to the decorator chain. + /// Передаёт аргументы конструктора цепочке декораторов. + /// USE_ALL_BASE_CONSTRUCTORS(Decorated, base) }; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/DecoratedBase.h b/cpp/Platform.Interfaces/DecoratedBase.h index e274a85..a55537b 100644 --- a/cpp/Platform.Interfaces/DecoratedBase.h +++ b/cpp/Platform.Interfaces/DecoratedBase.h @@ -3,10 +3,38 @@ #include "Macros.h" namespace Platform::Interfaces { + /// + /// Builds the decorator chain for a facade and its decorated object. + /// Создаёт цепочку декораторов для фасада и декорируемого объекта. + /// + /// + /// The facade type. + /// Тип фасада. + /// + /// + /// The decorated object type. + /// Тип декорируемого объекта. + /// + /// + /// The first decorator template. + /// Шаблон первого декоратора. + /// + /// + /// The remaining decorator templates. + /// Шаблоны остальных декораторов. + /// template typename TFirstDecorator, template typename... TDecorators> struct DecoratedBase : public DECORATED_BASE_TYPE(DecoratedBase, TFacade, TDecorated, TFirstDecorator, TDecorators) { + /// + /// The base type of the decorator chain. + /// Базовый тип цепочки декораторов. + /// using base = DECORATED_BASE_TYPE(DecoratedBase, TFacade, TDecorated, TFirstDecorator, TDecorators); + /// + /// Forwards constructor arguments to the next decorator. + /// Передаёт аргументы конструктора следующему декоратору. + /// USE_ALL_BASE_CONSTRUCTORS(DecoratedBase, base) }; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/DecoratorBase.h b/cpp/Platform.Interfaces/DecoratorBase.h index 98488e7..bc9e748 100644 --- a/cpp/Platform.Interfaces/DecoratorBase.h +++ b/cpp/Platform.Interfaces/DecoratorBase.h @@ -3,11 +3,35 @@ #include "Macros.h" namespace Platform::Interfaces { + /// + /// Provides typed access to a decorated object and its facade. + /// Предоставляет типизированный доступ к декорируемому объекту и его фасаду. + /// + /// + /// The facade type. + /// Тип фасада. + /// + /// + /// The decorated object type. + /// Тип декорируемого объекта. + /// template struct DecoratorBase : public TDecorated { + /// + /// Forwards constructor arguments to the decorated type. + /// Передаёт аргументы конструктора декорируемому типу. + /// USE_ALL_BASE_CONSTRUCTORS(DecoratorBase, TDecorated) + /// + /// Accesses the decorated object with the reference category of this object. + /// Предоставляет доступ к декорируемому объекту с соответствующей категорией ссылки. + /// THIS_REFERENCE_WRAPPER_METHODS(decorated, TDecorated) + /// + /// Accesses the facade with the reference category of this object. + /// Предоставляет доступ к фасаду с соответствующей категорией ссылки. + /// THIS_REFERENCE_WRAPPER_METHODS(facade, TFacade) }; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/Extended.h b/cpp/Platform.Interfaces/Extended.h index da763ee..14b3467 100644 --- a/cpp/Platform.Interfaces/Extended.h +++ b/cpp/Platform.Interfaces/Extended.h @@ -4,6 +4,22 @@ #include "Macros.h" namespace Platform::Interfaces { + /// + /// Composes one or more extenders around an object. + /// Объединяет одно или несколько расширений вокруг объекта. + /// + /// + /// The extendable object type. + /// Тип расширяемого объекта. + /// + /// + /// The first extender template. + /// Шаблон первого расширения. + /// + /// + /// The remaining extender templates. + /// Шаблоны остальных расширений. + /// template typename TFirstExtender, template typename... TExtenders> class Extended : public EXTENDED_BASE_TYPE(Extended, ExtendedBase, TExtendable, TFirstExtender, TExtenders) {}; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/ExtendedBase.h b/cpp/Platform.Interfaces/ExtendedBase.h index 1a5c0b5..d0db2e1 100644 --- a/cpp/Platform.Interfaces/ExtendedBase.h +++ b/cpp/Platform.Interfaces/ExtendedBase.h @@ -3,8 +3,20 @@ #include "Macros.h" namespace Platform::Interfaces { + /// + /// Provides typed access to the object being extended. + /// Предоставляет типизированный доступ к расширяемому объекту. + /// + /// + /// The extendable object type. + /// Тип расширяемого объекта. + /// template struct ExtendedBase : public TExtendable { + /// + /// Accesses the extended object with the reference category of this object. + /// Предоставляет доступ к расширяемому объекту с соответствующей категорией ссылки. + /// THIS_REFERENCE_WRAPPER_METHODS(extended, TExtendable) }; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/ExtendedContainer.h b/cpp/Platform.Interfaces/ExtendedContainer.h index 707f8ad..14438d6 100644 --- a/cpp/Platform.Interfaces/ExtendedContainer.h +++ b/cpp/Platform.Interfaces/ExtendedContainer.h @@ -4,6 +4,22 @@ #include "Macros.h" namespace Platform::Interfaces { + /// + /// Composes extenders around an object stored by value. + /// Объединяет расширения вокруг объекта, хранимого по значению. + /// + /// + /// The extendable object type. + /// Тип расширяемого объекта. + /// + /// + /// The first extender template. + /// Шаблон первого расширения. + /// + /// + /// The remaining extender templates. + /// Шаблоны остальных расширений. + /// template typename TFirstExtender, template typename... TExtenders> class ExtendedContainer : public EXTENDED_BASE_TYPE(ExtendedContainer, ExtendedContainerBase, TExtendable, TFirstExtender, TExtenders) {}; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/ExtendedContainerBase.h b/cpp/Platform.Interfaces/ExtendedContainerBase.h index 87f1eb0..3395637 100644 --- a/cpp/Platform.Interfaces/ExtendedContainerBase.h +++ b/cpp/Platform.Interfaces/ExtendedContainerBase.h @@ -3,12 +3,28 @@ #include "Macros.h" namespace Platform::Interfaces { + /// + /// Stores an extendable object by value and exposes it to derived types. + /// Хранит расширяемый объект по значению и предоставляет его производным типам. + /// + /// + /// The extendable object type. + /// Тип расширяемого объекта. + /// template class ExtendedContainerBase { public: + /// + /// Accesses the stored object with the reference category of this object. + /// Предоставляет доступ к хранимому объекту с соответствующей категорией ссылки. + /// VARIABLE_WRAPPER_METHODS(extended, extendable) protected: + /// + /// The stored extendable object. + /// Хранимый расширяемый объект. + /// TExtendable extendable; }; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/ExtendedReference.h b/cpp/Platform.Interfaces/ExtendedReference.h index 9313f67..c2cdbb3 100644 --- a/cpp/Platform.Interfaces/ExtendedReference.h +++ b/cpp/Platform.Interfaces/ExtendedReference.h @@ -4,11 +4,35 @@ #include "Macros.h" namespace Platform::Interfaces { + /// + /// Composes extenders around an object stored by reference. + /// Объединяет расширения вокруг объекта, хранимого по ссылке. + /// + /// + /// The extendable object type. + /// Тип расширяемого объекта. + /// + /// + /// The first extender template. + /// Шаблон первого расширения. + /// + /// + /// The remaining extender templates. + /// Шаблоны остальных расширений. + /// template typename TFirstExtender, template typename... TExtenders> class ExtendedReference : public EXTENDED_BASE_TYPE(ExtendedReference, ExtendedReferenceBase, TExtendable, TFirstExtender, TExtenders) { + /// + /// The composed extender base type. + /// Тип базовой цепочки расширений. + /// using base = EXTENDED_BASE_TYPE(ExtendedReference, ExtendedReferenceBase, TExtendable, TFirstExtender, TExtenders); public: + /// + /// Forwards constructor arguments to the extender chain. + /// Передаёт аргументы конструктора цепочке расширений. + /// USE_ALL_BASE_CONSTRUCTORS(ExtendedReference, base) }; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/ExtendedReferenceBase.h b/cpp/Platform.Interfaces/ExtendedReferenceBase.h index ecd077f..b4864d3 100644 --- a/cpp/Platform.Interfaces/ExtendedReferenceBase.h +++ b/cpp/Platform.Interfaces/ExtendedReferenceBase.h @@ -3,14 +3,38 @@ #include "Macros.h" namespace Platform::Interfaces { + /// + /// Stores an extendable object by reference and exposes it to derived types. + /// Хранит расширяемый объект по ссылке и предоставляет его производным типам. + /// + /// + /// The extendable object type. + /// Тип расширяемого объекта. + /// template class ExtendedReferenceBase { public: + /// + /// Stores a reference to an extendable object. + /// Сохраняет ссылку на расширяемый объект. + /// + /// + /// The object to extend. + /// Расширяемый объект. + /// ExtendedReferenceBase(TExtendable& reference) : extendable(reference) {} + /// + /// Accesses the referenced object with the reference category of this object. + /// Предоставляет доступ к объекту по ссылке с соответствующей категорией ссылки. + /// VARIABLE_WRAPPER_METHODS(extended, extendable) protected: + /// + /// The referenced extendable object. + /// Расширяемый объект по ссылке. + /// TExtendable& extendable; }; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/ICli.h b/cpp/Platform.Interfaces/ICli.h index 86edc18..b7356b9 100644 --- a/cpp/Platform.Interfaces/ICli.h +++ b/cpp/Platform.Interfaces/ICli.h @@ -23,6 +23,10 @@ namespace Platform::Interfaces { /// virtual int Run(const std::vector& args) = 0; + /// + /// Destroys the interface instance. + /// Уничтожает экземпляр интерфейса. + /// virtual ~ICli() = default; }; -} // namespace Platform::Interfaces \ No newline at end of file +} // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/ICounter[TResult, TArgument].h b/cpp/Platform.Interfaces/ICounter[TResult, TArgument].h index 0009155..06636c0 100644 --- a/cpp/Platform.Interfaces/ICounter[TResult, TArgument].h +++ b/cpp/Platform.Interfaces/ICounter[TResult, TArgument].h @@ -1,13 +1,45 @@ #pragma once namespace Platform::Interfaces { + /// + /// Declares the primary counter interface template for its supported specializations. + /// Объявляет основной шаблон интерфейса счётчика для поддерживаемых специализаций. + /// template struct ICounter; + /// + /// Defines a counter that requires an argument to perform a count. + /// Определяет счётчик, которому требуется аргумент для выполнения подсчёта. + /// + /// + /// The count result type. + /// Тип результата подсчёта. + /// + /// + /// The argument type. + /// Тип аргумента. + /// template struct ICounter { + /// + /// Performs a count. + /// Выполняет подсчёт. + /// + /// + /// The argument. + /// Аргумент. + /// + /// + /// The count result. + /// Результат подсчёта. + /// virtual TResult Count(TArgument argument) = 0; + /// + /// Destroys the interface instance. + /// Уничтожает экземпляр интерфейса. + /// virtual ~ICounter() = default; }; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/ICounter[TResult].h b/cpp/Platform.Interfaces/ICounter[TResult].h index 44db546..0de0de5 100644 --- a/cpp/Platform.Interfaces/ICounter[TResult].h +++ b/cpp/Platform.Interfaces/ICounter[TResult].h @@ -1,13 +1,37 @@ #pragma once namespace Platform::Interfaces { + /// + /// Declares the primary counter interface template for its supported specializations. + /// Объявляет основной шаблон интерфейса счётчика для поддерживаемых специализаций. + /// template struct ICounter; + /// + /// Defines a counter. + /// Определяет счётчик. + /// + /// + /// The count result type. + /// Тип результата подсчёта. + /// template struct ICounter { + /// + /// Performs a count. + /// Выполняет подсчёт. + /// + /// + /// The count result. + /// Результат подсчёта. + /// virtual TResult Count() = 0; + /// + /// Destroys the interface instance. + /// Уничтожает экземпляр интерфейса. + /// virtual ~ICounter() = default; }; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/IFactory.h b/cpp/Platform.Interfaces/IFactory.h index 5d7c6b3..c859db9 100644 --- a/cpp/Platform.Interfaces/IFactory.h +++ b/cpp/Platform.Interfaces/IFactory.h @@ -1,13 +1,37 @@ #pragma once namespace Platform::Interfaces { + /// + /// Declares the primary factory interface template. + /// Объявляет основной шаблон интерфейса фабрики. + /// template struct IFactory; + /// + /// Defines a factory that produces instances of a specific type. + /// Определяет фабрику, которая производит экземпляры определенного типа. + /// + /// + /// Type of produced instances. + /// Тип производимых экземпляров. + /// template struct IFactory { + /// + /// Creates an instance of TProduct type. + /// Создает экземпляр типа TProduct. + /// + /// + /// The instance of TProduct type. + /// Экземпляр типа TProduct. + /// virtual TProduct Create() = 0; + /// + /// Destroys the interface instance. + /// Уничтожает экземпляр интерфейса. + /// virtual ~IFactory() = default; }; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/IMatcher.h b/cpp/Platform.Interfaces/IMatcher.h index 017f96b..a339590 100644 --- a/cpp/Platform.Interfaces/IMatcher.h +++ b/cpp/Platform.Interfaces/IMatcher.h @@ -1,13 +1,41 @@ #pragma once namespace Platform::Interfaces { + /// + /// Declares the primary matcher interface template. + /// Объявляет основной шаблон интерфейса сопоставления. + /// template struct IMatcher; + /// + /// Defines a matcher that determines whether a candidate satisfies its matching rule. + /// Определяет объект, который проверяет, соответствует ли кандидат правилу сопоставления. + /// + /// + /// Type of the value being tested for a match. + /// Тип значения, проверяемого на соответствие. + /// template struct IMatcher { + /// + /// Determines whether the candidate satisfies the matching rule. + /// Определяет, соответствует ли кандидат правилу сопоставления. + /// + /// + /// The value to test. + /// Проверяемое значение. + /// + /// + /// Whether the candidate satisfies the matching rule. + /// Соответствует ли кандидат правилу сопоставления. + /// virtual bool IsMatched(TCandidate candidate) = 0; + /// + /// Destroys the interface instance. + /// Уничтожает экземпляр интерфейса. + /// virtual ~IMatcher() = default; }; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/IProperties.h b/cpp/Platform.Interfaces/IProperties.h index ff0871c..7885d06 100644 --- a/cpp/Platform.Interfaces/IProperties.h +++ b/cpp/Platform.Interfaces/IProperties.h @@ -1,15 +1,71 @@ #pragma once namespace Platform::Interfaces { + /// + /// Declares the primary properties operator interface template. + /// Объявляет основной шаблон интерфейса оператора свойств. + /// template struct IProperties; + /// + /// Defines a properties operator that is able to get or set values of properties of a object of a specific type. + /// Определяет оператор свойств, который может получать или устанавливать значения свойств объекта определенного типа. + /// + /// + /// Object type. + /// Тип объекта. + /// + /// + /// Property reference type. + /// Тип ссылки на свойство. + /// + /// + /// Property value type. + /// Тип значения свойства. + /// template struct IProperties { + /// + /// Gets the value of the property in the specified object. + /// Получает значение свойства в указанном объекте. + /// + /// + /// The object reference. + /// Ссылка на объект. + /// + /// + /// The property reference. + /// Ссылка на свойство. + /// + /// + /// The value of the property. + /// Значение свойства. + /// virtual TValue GetValue(TObject object, TProperty property) = 0; + /// + /// Sets the value of a property in the specified object. + /// Устанавливает значение свойства в указанном объекте. + /// + /// + /// The object reference. + /// Ссылка на объект. + /// + /// + /// The property reference. + /// Ссылка на свойство. + /// + /// + /// The value. + /// Значение. + /// virtual void SetValue(TObject object, TProperty property, TValue value) = 0; + /// + /// Destroys the interface instance. + /// Уничтожает экземпляр интерфейса. + /// virtual ~IProperties() = default; }; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/IProperty.h b/cpp/Platform.Interfaces/IProperty.h index f36e9e9..97b70a0 100644 --- a/cpp/Platform.Interfaces/IProperty.h +++ b/cpp/Platform.Interfaces/IProperty.h @@ -4,11 +4,31 @@ #include "ISetter[TValue, TArgument].h" namespace Platform::Interfaces { + /// + /// Declares the primary property operator interface template. + /// Объявляет основной шаблон интерфейса оператора свойства. + /// template struct IProperty; + /// + /// Defines a specific property operator that is able to get or set values of that property. + /// Определяет оператор определённого свойства, который может получать или устанавливать его значения. + /// + /// + /// Object type. + /// Тип объекта. + /// + /// + /// Property value type. + /// Тип значения свойства. + /// template struct IProperty : public ISetter, IProvider { + /// + /// Destroys the interface instance. + /// Уничтожает экземпляр интерфейса. + /// virtual ~IProperty() = default; }; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/IProvider[TProvided, TArgument].h b/cpp/Platform.Interfaces/IProvider[TProvided, TArgument].h index 119cadc..eb81d7d 100644 --- a/cpp/Platform.Interfaces/IProvider[TProvided, TArgument].h +++ b/cpp/Platform.Interfaces/IProvider[TProvided, TArgument].h @@ -1,13 +1,45 @@ #pragma once namespace Platform::Interfaces { + /// + /// Declares the primary provider interface template for its supported specializations. + /// Объявляет основной шаблон интерфейса поставщика для поддерживаемых специализаций. + /// template struct IProvider; + /// + /// Defines the provider of objects/values for which an argument must be specified. + /// Определяет поставщика объектов/значений, для получения которых необходимо указать аргумент. + /// + /// + /// Type of provided objects/values. + /// Тип предоставляемых объектов/значений. + /// + /// + /// Argument type. + /// Тип аргумента. + /// template struct IProvider { + /// + /// Provides an object(s)/value(s). + /// Предоставляет объект(ы)/значение(я). + /// + /// + /// The argument required to acquire the object(s)/value(s). + /// Аргумент, необходимый для получения объекта(ов)/значения(ий). + /// + /// + /// The object(s)/value(s). + /// Объект(ы)/значение(я). + /// virtual TProvided Get(TArgument argument) = 0; + /// + /// Destroys the interface instance. + /// Уничтожает экземпляр интерфейса. + /// virtual ~IProvider() = default; }; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/IProvider[TProvided].h b/cpp/Platform.Interfaces/IProvider[TProvided].h index 2f035f3..0609464 100644 --- a/cpp/Platform.Interfaces/IProvider[TProvided].h +++ b/cpp/Platform.Interfaces/IProvider[TProvided].h @@ -1,13 +1,37 @@ #pragma once namespace Platform::Interfaces { + /// + /// Declares the primary provider interface template for its supported specializations. + /// Объявляет основной шаблон интерфейса поставщика для поддерживаемых специализаций. + /// template struct IProvider; + /// + /// Defines the provider of objects/values. + /// Определяет поставщика объектов/значений. + /// + /// + /// Type of provided object/value. + /// Тип предоставляемого объекта/значения. + /// template struct IProvider { + /// + /// Provides an object(s)/value(s). + /// Предоставляет объект(ы)/значение(я). + /// + /// + /// The object(s)/value(s). + /// Объект(ы)/значение(я). + /// virtual TProvided Get() = 0; + /// + /// Destroys the interface instance. + /// Уничтожает экземпляр интерфейса. + /// virtual ~IProvider() = default; }; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/ISetter[TValue, TArgument].h b/cpp/Platform.Interfaces/ISetter[TValue, TArgument].h index 52ed8b9..805cfaf 100644 --- a/cpp/Platform.Interfaces/ISetter[TValue, TArgument].h +++ b/cpp/Platform.Interfaces/ISetter[TValue, TArgument].h @@ -1,13 +1,45 @@ #pragma once namespace Platform::Interfaces { + /// + /// Declares the primary setter interface template for its supported specializations. + /// Объявляет основной шаблон интерфейса установщика для поддерживаемых специализаций. + /// template struct ISetter; + /// + /// Defines an setter that requires an argument to set the passed value as a new state. + /// Определяет установщик, которому для установки переданного значения в качестве нового состояния требуется аргумент. + /// + /// + /// Type of set value. + /// Тип устанавливаемого значения. + /// + /// + /// The argument type. + /// Тип аргумента. + /// template struct ISetter { + /// + /// Sets the value of a specific property in the specified object. + /// Устанавливает значение определённого свойства в указанном объекте. + /// + /// + /// The argument. + /// Аргумент. + /// + /// + /// The value. + /// Значение. + /// virtual void Set(TArgument argument, TValue value) = 0; + /// + /// Destroys the interface instance. + /// Уничтожает экземпляр интерфейса. + /// virtual ~ISetter() = default; }; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/ISetter[TValue].h b/cpp/Platform.Interfaces/ISetter[TValue].h index a893933..f49d75b 100644 --- a/cpp/Platform.Interfaces/ISetter[TValue].h +++ b/cpp/Platform.Interfaces/ISetter[TValue].h @@ -1,13 +1,37 @@ #pragma once namespace Platform::Interfaces { + /// + /// Declares the primary setter interface template for its supported specializations. + /// Объявляет основной шаблон интерфейса установщика для поддерживаемых специализаций. + /// template struct ISetter; + /// + /// Defines an setter that sets the passed value as a new state. + /// Определяет установщик, который устанавливает переданное значение в качестве нового состояния. + /// + /// + /// Type of set value. + /// Тип устанавливаемого значения. + /// template struct ISetter { + /// + /// Sets the value of a specific property in the specified object. + /// Устанавливает значение определённого свойства в указанном объекте. + /// + /// + /// The value. + /// Значение. + /// virtual void Set(TValue value) = 0; + /// + /// Destroys the interface instance. + /// Уничтожает экземпляр интерфейса. + /// virtual ~ISetter() = default; }; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/Macros.h b/cpp/Platform.Interfaces/Macros.h index 061b5e0..5f3bc6c 100644 --- a/cpp/Platform.Interfaces/Macros.h +++ b/cpp/Platform.Interfaces/Macros.h @@ -5,26 +5,50 @@ #include namespace Platform::Interfaces { +/// +/// Generates four reference-qualified accessors that cast this object to the wrapped type. +/// Создаёт четыре метода доступа с квалификаторами ссылки, приводящие объект к обёрнутому типу. +/// #define THIS_REFERENCE_WRAPPER_METHODS(MethodName, TWrapped) \ constexpr auto&& MethodName()& { return static_cast(*this); } \ constexpr auto&& MethodName()&& { return static_cast(*this); } \ constexpr auto&& MethodName() const& { return static_cast(*this); } \ constexpr auto&& MethodName() const&& { return static_cast(*this); } +/// +/// Generates four reference-qualified accessors for a member variable. +/// Создаёт четыре метода доступа с квалификаторами ссылки для поля. +/// #define VARIABLE_WRAPPER_METHODS(MethodName, VariableName) \ constexpr auto&& MethodName()& { return VariableName; } \ constexpr auto&& MethodName()&& { return VariableName; } \ constexpr auto&& MethodName() const& { return VariableName; } \ constexpr auto&& MethodName() const&& { return VariableName; } +/// +/// Selects the next type in an extender chain. +/// Выбирает следующий тип в цепочке расширений. +/// #define EXTENDED_BASE_TYPE(TExtended, TExtendedBase, TExtendable, TFirstExtender, TExtenders) TFirstExtender= 2, TExtended, std::tuple_element_t<0, std::tuple>...>>>> +/// +/// Selects the next type in a decorator chain. +/// Выбирает следующий тип в цепочке декораторов. +/// #define DECORATED_BASE_TYPE(TDecoratedBase, TFacade, TDecorated, TFirstDecorator, TDecorators) TFirstDecorator= 2, TDecoratedBase, std::tuple_element_t<0, std::tuple...>>>> +/// +/// Generates a forwarding constructor for the specified base type. +/// Создаёт конструктор с передачей аргументов указанному базовому типу. +/// #define USE_ALL_BASE_CONSTRUCTORS(TSelf, TBase) \ template \ TSelf(TParams&&... params) : TBase(std::forward(params)...) {} +/// +/// Calls a method directly for a concrete type or virtually for an abstract type. +/// Вызывает метод напрямую для конкретного типа или виртуально для абстрактного типа. +/// #define DIRECT_METHOD_CALL(TClass, Object, MethodName, ...) (std::is_abstract::value ? Object.MethodName(__VA_ARGS__) : Object.TClass::MethodName(__VA_ARGS__)) } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/Platform.Interfaces.TemplateLibrary.nuspec b/cpp/Platform.Interfaces/Platform.Interfaces.TemplateLibrary.nuspec index c7be134..6624589 100644 --- a/cpp/Platform.Interfaces/Platform.Interfaces.TemplateLibrary.nuspec +++ b/cpp/Platform.Interfaces/Platform.Interfaces.TemplateLibrary.nuspec @@ -5,8 +5,8 @@ LinksPlatform's Platform.Interfaces Template Library LinksPlatform's Platform.Interfaces is a Template Library what contains common concepts templates. LinksPlatform's Platform.Interfaces is a Template Library what contains set of C++ concepts templates. Use Platform.Interfaces.h file to include the library. - Breaking change: rename ICriterionMatcher to IMatcher and CCriterionMatcher to CMatcher. Update header includes and references. - 0.4.0 + Add bilingual documentation for the complete public C++ API and validate generated API documentation in CI. + 0.4.1 konard, uselessgoddess, Mitron57 konard, uselessgoddess, Mitron57 konard, uselessgoddess, Mitron57 diff --git a/cpp/Platform.Interfaces/Polymorph.h b/cpp/Platform.Interfaces/Polymorph.h index e182ffe..00340c3 100644 --- a/cpp/Platform.Interfaces/Polymorph.h +++ b/cpp/Platform.Interfaces/Polymorph.h @@ -3,9 +3,25 @@ #include "Macros.h" namespace Platform::Interfaces { + /// + /// Combines base types and exposes the derived object to them. + /// Объединяет базовые типы и предоставляет им доступ к производному объекту. + /// + /// + /// The type checked by this concept or described by this helper. + /// Тип, проверяемый этим концептом или описываемый этим вспомогательным типом. + /// + /// + /// The base types. + /// Базовые типы. + /// template class Polymorph : public TBase... { protected: + /// + /// Accesses the derived object with the reference category of this object. + /// Предоставляет доступ к производному объекту с соответствующей категорией ссылки. + /// THIS_REFERENCE_WRAPPER_METHODS(object, TSelf) }; } // namespace Platform::Interfaces diff --git a/csharp/Platform.Interfaces/Platform.Interfaces.csproj b/csharp/Platform.Interfaces/Platform.Interfaces.csproj index f05f43f..ca685ab 100644 --- a/csharp/Platform.Interfaces/Platform.Interfaces.csproj +++ b/csharp/Platform.Interfaces/Platform.Interfaces.csproj @@ -4,7 +4,7 @@ LinksPlatform's Platform.Interfaces Class Library Konstantin Diachenko Platform.Interfaces - 0.6.0 + 0.6.1 Konstantin Diachenko net8 Platform.Interfaces @@ -23,7 +23,7 @@ true embedded latest - Breaking change: rename ICriterionMatcher to IMatcher. Matcher input is named candidate; update implementations and references to the new interface. + Validate complete bilingual English and Russian XML documentation for the public C# API in CI. enable