/
niceSOFT
/
swig
Обзор
Документация
Войти
/
niceSOFT
/
swig
Код
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
Examples/test-suite/cpp20_concepts.i
135 строк
4 KB
William S Fulton
C++20 concepts: embed in the parse tree and reject %template instantiation
10 май 2026, 19:37
10 май 2026, 19:37
495aaee
Код
Авторство
О чём код?
%module cpp20_concepts // SWIG provides only basic parser level support for C++20 concept declarations // and requires-clauses: both are silently consumed and produce no node in the // parse tree, so a constrained template wraps as if it were unconstrained. %inline %{ #include <concepts> template<typename T> concept Numeric = std::integral<T> || std::floating_point<T>; // A concept whose body refers to another concept (and uses sizeof in a // parenthesised subexpression to exercise paren tracking in the skipper). template<typename T> concept SmallNumeric = Numeric<T> && (sizeof(T) <= 4); // Function template with a trailing requires-clause. template<typename T> T cube(T x) requires Numeric<T> { return x * x * x; } // Function template with a prefix requires-clause - the constraint sits // between the template head and the return type. template<typename T> requires Numeric<T> T quad(T x) { return x * x * x * x; } // Prefix requires-clause with a compound constraint joined by '&&'. template<typename T> requires Numeric<T> && SmallNumeric<T> T half(T x) { return x / 2; } // Prefix requires-clause with a parenthesised constraint subexpression. template<typename T> requires (Numeric<T> || std::same_as<T, bool>) T identity(T x) { return x; } // Trailing requires-clause whose constraint contains a requires-expression // as a primary - the inner '{ t + t; }' is part of the constraint, not the // function body. template<typename T> T add(T a, T b) requires requires (T t) { t + t; } { T result = a + b; return result; } // A concept whose body is itself a requires-expression. Functionally // equivalent to the Addable variable template in cpp20_variable_templates.i, // but spelt as a named concept usable as a constraint. template<typename T> concept Summable = requires (T t) { t + t; }; template<typename T> T sum_pair(T a, T b) requires Summable<T> { return a + b; } // A concept whose body is a requires-expression containing a compound // requirement with a trailing return type constraint - '{ a + b } -> std::same_as<T>;' template<typename T> concept AddableSame = requires(T a, T b) { { a + b } -> std::same_as<T>; }; template<typename T> T add_same(T a, T b) requires AddableSame<T> { return a + b; } // Inline 'requires requires' with a compound requirement. template<typename T> T add_inline_same(T a, T b) requires requires(T x, T y) { { x + y } -> std::same_as<T>; } { return a + b; } // Concept body with multiple simple-requirements. struct Engine { bool running = false; void start() { running = true; } void stop() { running = false; } }; template<typename T> concept Machine = requires(T m) { m.start(); m.stop(); }; template<typename T> bool cycle(T& m) requires Machine<T> { m.start(); m.stop(); return true; } // Concept body with a type-requirement, a noexcept compound-requirement and // a nested-requirement alongside a simple-requirement. struct Container { using value_type = int; void push_back(int) noexcept {} }; template<typename T> concept BasicContainer = requires(T c, typename T::value_type v) { typename T::value_type; { c.push_back(v) } noexcept; requires sizeof(T) > 0; }; template<typename T> bool check_container(T c) requires BasicContainer<T> { return true; } %} %template(cube_int) cube<int>; %template(cube_double) cube<double>; %template(quad_int) quad<int>; %template(quad_double) quad<double>; %template(half_int) half<int>; %template(identity_int) identity<int>; %template(add_int) add<int>; %template(sum_pair_int) sum_pair<int>; %template(add_same_int) add_same<int>; %template(add_inline_same_int) add_inline_same<int>; %template(cycle_engine) cycle<Engine>; %template(check_container_c) check_container<Container>;