tpy-lang 0.3.0.dev0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tpy_lang-0.3.0.dev0.dist-info/METADATA +151 -0
- tpy_lang-0.3.0.dev0.dist-info/RECORD +333 -0
- tpy_lang-0.3.0.dev0.dist-info/WHEEL +4 -0
- tpy_lang-0.3.0.dev0.dist-info/entry_points.txt +3 -0
- tpyc/__init__.py +104 -0
- tpyc/__main__.py +6 -0
- tpyc/_buildinfo.py +1 -0
- tpyc/_data/docs/LANGUAGE_FEATURES.md +6278 -0
- tpyc/_data/docs/STDLIB_ROADMAP.md +1258 -0
- tpyc/_data/docs/TPY_FOR_AGENTS.md +556 -0
- tpyc/_data/lib/tpy/_bindings/__init__.py +6 -0
- tpyc/_data/lib/tpy/_bindings/pcre2.py +173 -0
- tpyc/_data/lib/tpy/_bindings/posix_socket.py +161 -0
- tpyc/_data/lib/tpy/_functools_macros.py +80 -0
- tpyc/_data/lib/tpy/_macro_helpers.py +161 -0
- tpyc/_data/lib/tpy/argparse.py +2062 -0
- tpyc/_data/lib/tpy/asyncio/__init__.py +744 -0
- tpyc/_data/lib/tpy/asyncio/_executor.py +515 -0
- tpyc/_data/lib/tpy/base64.py +410 -0
- tpyc/_data/lib/tpy/bisect.py +39 -0
- tpyc/_data/lib/tpy/builtins.py +38 -0
- tpyc/_data/lib/tpy/dataclasses.py +354 -0
- tpyc/_data/lib/tpy/enum.py +23 -0
- tpyc/_data/lib/tpy/functools.py +33 -0
- tpyc/_data/lib/tpy/hashlib.py +206 -0
- tpyc/_data/lib/tpy/heapq.py +118 -0
- tpyc/_data/lib/tpy/io.py +395 -0
- tpyc/_data/lib/tpy/json.py +221 -0
- tpyc/_data/lib/tpy/math.py +406 -0
- tpyc/_data/lib/tpy/random.py +597 -0
- tpyc/_data/lib/tpy/re.py +467 -0
- tpyc/_data/lib/tpy/socket.py +379 -0
- tpyc/_data/lib/tpy/struct.py +178 -0
- tpyc/_data/lib/tpy/sys.py +40 -0
- tpyc/_data/lib/tpy/time.py +39 -0
- tpyc/_data/lib/tpy/tpy/__init__.py +78 -0
- tpyc/_data/lib/tpy/tpy/_bootstrap/__init__.py +10 -0
- tpyc/_data/lib/tpy/tpy/_bootstrap/_decorators.py +37 -0
- tpyc/_data/lib/tpy/tpy/_bootstrap/_extern.py +64 -0
- tpyc/_data/lib/tpy/tpy/_builtins/__init__.py +11 -0
- tpyc/_data/lib/tpy/tpy/_builtins/_bytes.py +378 -0
- tpyc/_data/lib/tpy/tpy/_builtins/_dict.py +151 -0
- tpyc/_data/lib/tpy/tpy/_builtins/_exceptions.py +125 -0
- tpyc/_data/lib/tpy/tpy/_builtins/_funcs.py +681 -0
- tpyc/_data/lib/tpy/tpy/_builtins/_io.py +97 -0
- tpyc/_data/lib/tpy/tpy/_builtins/_list.py +127 -0
- tpyc/_data/lib/tpy/tpy/_builtins/_range.py +52 -0
- tpyc/_data/lib/tpy/tpy/_builtins/_set.py +139 -0
- tpyc/_data/lib/tpy/tpy/_builtins/_super.py +11 -0
- tpyc/_data/lib/tpy/tpy/_builtins/_types.py +661 -0
- tpyc/_data/lib/tpy/tpy/_core/__init__.py +23 -0
- tpyc/_data/lib/tpy/tpy/_core/_bytes_view.py +129 -0
- tpyc/_data/lib/tpy/tpy/_core/_containers.py +137 -0
- tpyc/_data/lib/tpy/tpy/_core/_functions.py +40 -0
- tpyc/_data/lib/tpy/tpy/_core/_types.py +2061 -0
- tpyc/_data/lib/tpy/tpy/_typing/__init__.py +77 -0
- tpyc/_data/lib/tpy/tpy/_version.py +29 -0
- tpyc/_data/lib/tpy/tpy/bits.py +28 -0
- tpyc/_data/lib/tpy/tpy/coro/__init__.py +127 -0
- tpyc/_data/lib/tpy/tpy/extern.py +8 -0
- tpyc/_data/lib/tpy/tpy/mem.py +49 -0
- tpyc/_data/lib/tpy/tpy/unsafe.py +195 -0
- tpyc/_data/lib/tpy/tpy/version.py +21 -0
- tpyc/_data/lib/tpy/typing.py +13 -0
- tpyc/_data/runtime/cpp/include/tpy/any.hpp +461 -0
- tpyc/_data/runtime/cpp/include/tpy/as_ostream.hpp +117 -0
- tpyc/_data/runtime/cpp/include/tpy/async.hpp +76 -0
- tpyc/_data/runtime/cpp/include/tpy/bigint.hpp +1343 -0
- tpyc/_data/runtime/cpp/include/tpy/builtins.hpp +400 -0
- tpyc/_data/runtime/cpp/include/tpy/bytes_ops.hpp +469 -0
- tpyc/_data/runtime/cpp/include/tpy/container_ops.hpp +487 -0
- tpyc/_data/runtime/cpp/include/tpy/copy_iter.hpp +82 -0
- tpyc/_data/runtime/cpp/include/tpy/core.hpp +558 -0
- tpyc/_data/runtime/cpp/include/tpy/dict_ops.hpp +289 -0
- tpyc/_data/runtime/cpp/include/tpy/dunder.hpp +750 -0
- tpyc/_data/runtime/cpp/include/tpy/dynamic.hpp +44 -0
- tpyc/_data/runtime/cpp/include/tpy/enum.hpp +40 -0
- tpyc/_data/runtime/cpp/include/tpy/file.hpp +245 -0
- tpyc/_data/runtime/cpp/include/tpy/fixed_int.hpp +317 -0
- tpyc/_data/runtime/cpp/include/tpy/format.hpp +954 -0
- tpyc/_data/runtime/cpp/include/tpy/frame_slot.hpp +120 -0
- tpyc/_data/runtime/cpp/include/tpy/generator.hpp +47 -0
- tpyc/_data/runtime/cpp/include/tpy/iterable_ops.hpp +122 -0
- tpyc/_data/runtime/cpp/include/tpy/itertools.hpp +749 -0
- tpyc/_data/runtime/cpp/include/tpy/next_iter.hpp +82 -0
- tpyc/_data/runtime/cpp/include/tpy/ordered_map.hpp +518 -0
- tpyc/_data/runtime/cpp/include/tpy/ordered_set.hpp +337 -0
- tpyc/_data/runtime/cpp/include/tpy/own_iter.hpp +54 -0
- tpyc/_data/runtime/cpp/include/tpy/pascal_graph_sdl.hpp +192 -0
- tpyc/_data/runtime/cpp/include/tpy/printing.hpp +302 -0
- tpyc/_data/runtime/cpp/include/tpy/protocols.hpp +61 -0
- tpyc/_data/runtime/cpp/include/tpy/range.hpp +115 -0
- tpyc/_data/runtime/cpp/include/tpy/ranges.hpp +212 -0
- tpyc/_data/runtime/cpp/include/tpy/set_ops.hpp +265 -0
- tpyc/_data/runtime/cpp/include/tpy/slice.hpp +47 -0
- tpyc/_data/runtime/cpp/include/tpy/span_iter.hpp +42 -0
- tpyc/_data/runtime/cpp/include/tpy/stdlib/math.hpp +41 -0
- tpyc/_data/runtime/cpp/include/tpy/stdlib/pcre2_h.hpp +96 -0
- tpyc/_data/runtime/cpp/include/tpy/stdlib/random.hpp +25 -0
- tpyc/_data/runtime/cpp/include/tpy/stdlib/socket_h.hpp +145 -0
- tpyc/_data/runtime/cpp/include/tpy/stdlib/time.hpp +62 -0
- tpyc/_data/runtime/cpp/include/tpy/system.hpp +121 -0
- tpyc/_data/runtime/cpp/include/tpy/throwable.hpp +55 -0
- tpyc/_data/runtime/cpp/include/tpy/tpy.hpp +156 -0
- tpyc/_data/runtime/cpp/include/tpy/type_name.hpp +77 -0
- tpyc/_data/runtime/cpp/include/tpy/type_traits.hpp +240 -0
- tpyc/_data/runtime/cpp/include/tpy/uninit_array_storage.hpp +250 -0
- tpyc/_data/runtime/cpp/include/tpy/uninit_heap_storage.hpp +277 -0
- tpyc/_data/runtime/cpp/include/tpy/varargs.hpp +174 -0
- tpyc/_data/runtime/cpp/include/tpy/variant_ref.hpp +118 -0
- tpyc/_data/runtime/cpp/src/stdlib/socket_impl.cpp +104 -0
- tpyc/_data/runtime/cpp/third_party/README.md +58 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/AUTHORS +36 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/CMakeLists.txt +1233 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/COPYING +5 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/ChangeLog +3097 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/HACKING +853 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/INSTALL +368 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/LICENCE +94 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/NEWS +492 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/NON-AUTOTOOLS-BUILD +430 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/README +956 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/cmake/COPYING-CMAKE-SCRIPTS +22 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/cmake/FindEditline.cmake +16 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/cmake/FindPackageHandleStandardArgs.cmake +58 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/cmake/FindReadline.cmake +29 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/cmake/pcre2-config-version.cmake.in +15 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/cmake/pcre2-config.cmake.in +148 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/config-cmake.h.in +56 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/libpcre2-16.pc.in +13 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/libpcre2-32.pc.in +13 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/libpcre2-8.pc.in +13 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/libpcre2-posix.pc.in +13 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/pcre2-config.in +121 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/config.h +483 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/config.h.generic +483 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/config.h.in +460 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2.h +1010 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2.h.generic +1010 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2.h.in +1010 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_auto_possess.c +1371 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_chartables.c +196 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_chartables.c.dist +196 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_chkdint.c +96 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_compile.c +11001 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_config.c +252 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_context.c +510 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_convert.c +1189 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_dfa_match.c +4119 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_dftables.c +297 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_error.c +345 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_extuni.c +162 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_find_bracket.c +219 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_fuzzsupport.c +792 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_internal.h +2084 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_intmodedep.h +940 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_jit_compile.c +14972 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_jit_match.c +200 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_jit_misc.c +234 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_jit_neon_inc.h +354 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_jit_simd_inc.h +2355 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_jit_test.c +2528 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_maketables.c +165 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_match.c +7777 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_match_data.c +185 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_newline.c +243 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_ord2utf.c +120 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_pattern_info.c +432 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_printint.c +886 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_script_run.c +344 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_serialize.c +286 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_string_utils.c +237 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_study.c +1915 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_substitute.c +1009 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_substring.c +550 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_tables.c +234 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_ucd.c +5460 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_ucp.h +396 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_ucptables.c +1533 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_valid_utf.c +398 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_xclass.c +308 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2demo.c +497 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2grep.c +4606 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2posix.c +425 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2posix.h +187 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2posix_test.c +209 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2test.c +9708 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitExecAllocatorApple.c +137 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitExecAllocatorCore.c +327 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitExecAllocatorFreeBSD.c +89 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitExecAllocatorPosix.c +62 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitExecAllocatorWindows.c +40 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitProtExecAllocatorNetBSD.c +72 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitProtExecAllocatorPosix.c +172 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitWXExecAllocatorPosix.c +141 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitWXExecAllocatorWindows.c +102 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitConfig.h +142 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitConfigCPU.h +188 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitConfigInternal.h +907 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitLir.c +3561 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitLir.h +2466 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeARM_32.c +4636 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeARM_64.c +3491 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeARM_T2_32.c +4302 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeLOONGARCH_64.c +3765 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeMIPS_32.c +472 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeMIPS_64.c +387 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeMIPS_common.c +4259 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativePPC_32.c +485 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativePPC_64.c +719 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativePPC_common.c +3161 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeRISCV_32.c +142 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeRISCV_64.c +222 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeRISCV_common.c +3121 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeS390X.c +4526 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeX86_32.c +1685 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeX86_64.c +1398 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeX86_common.c +5001 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitSerialize.c +516 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitUtils.c +344 -0
- tpyc/_data/runtime/cpp/third_party/pcre2.sources.txt +54 -0
- tpyc/_data/runtime/cpp/third_party/pcre2.vendor.json +7 -0
- tpyc/build/__init__.py +7 -0
- tpyc/build/pcre2.py +122 -0
- tpyc/build/third_party.py +413 -0
- tpyc/cli.py +822 -0
- tpyc/codegen_cpp/__init__.py +18 -0
- tpyc/codegen_cpp/builtins.py +484 -0
- tpyc/codegen_cpp/context.py +2064 -0
- tpyc/codegen_cpp/expressions.py +5940 -0
- tpyc/codegen_cpp/functions.py +1913 -0
- tpyc/codegen_cpp/gen_async.py +3258 -0
- tpyc/codegen_cpp/gen_generators.py +657 -0
- tpyc/codegen_cpp/generator.py +2258 -0
- tpyc/codegen_cpp/match.py +1997 -0
- tpyc/codegen_cpp/param_const.py +172 -0
- tpyc/codegen_cpp/protocols.py +907 -0
- tpyc/codegen_cpp/records.py +1654 -0
- tpyc/codegen_cpp/resumable_cfg.py +1651 -0
- tpyc/codegen_cpp/statements.py +4963 -0
- tpyc/codegen_cpp/string_dispatch.py +76 -0
- tpyc/codegen_cpp/test_context.py +46 -0
- tpyc/codegen_cpp/test_param_const.py +113 -0
- tpyc/codegen_cpp/test_resumable_cfg.py +182 -0
- tpyc/codegen_cpp/type_resolution.py +53 -0
- tpyc/codegen_cpp/types.py +436 -0
- tpyc/codegen_cpp/variant_access.py +135 -0
- tpyc/coercions.py +749 -0
- tpyc/compilation_context.py +57 -0
- tpyc/compiler.py +3945 -0
- tpyc/cycle_detection.py +358 -0
- tpyc/diagnostics.py +135 -0
- tpyc/dump_types.py +353 -0
- tpyc/frontend_diagnostics.py +47 -0
- tpyc/frontend_ir/__init__.py +140 -0
- tpyc/frontend_ir/lower.py +1098 -0
- tpyc/frontend_ir/nodes.py +718 -0
- tpyc/frontend_ir/resolver_adapter.py +151 -0
- tpyc/frontend_plugin.py +209 -0
- tpyc/install_docs.py +81 -0
- tpyc/liveness.py +756 -0
- tpyc/macro_api.py +1724 -0
- tpyc/macro_loader.py +497 -0
- tpyc/module_names.py +64 -0
- tpyc/modules/__init__.py +31 -0
- tpyc/modules/defs.py +89 -0
- tpyc/modules/registry.py +36 -0
- tpyc/modules/resolver.py +192 -0
- tpyc/modules/type_resolution.py +629 -0
- tpyc/namespace.py +172 -0
- tpyc/parse/__init__.py +84 -0
- tpyc/parse/imports.py +490 -0
- tpyc/parse/nodes.py +1732 -0
- tpyc/parse/parser.py +4043 -0
- tpyc/parse/resolve_refs.py +466 -0
- tpyc/parse/type_resolver.py +1060 -0
- tpyc/prescan.py +254 -0
- tpyc/qnames.py +149 -0
- tpyc/repl.py +529 -0
- tpyc/repl_backends.py +848 -0
- tpyc/sema/__init__.py +21 -0
- tpyc/sema/analyzer.py +3625 -0
- tpyc/sema/bound_check.py +72 -0
- tpyc/sema/builder_trace.py +684 -0
- tpyc/sema/calls.py +5406 -0
- tpyc/sema/compatibility.py +2107 -0
- tpyc/sema/context.py +1243 -0
- tpyc/sema/expressions.py +3737 -0
- tpyc/sema/flow_facts.py +199 -0
- tpyc/sema/init_tracker.py +150 -0
- tpyc/sema/list_literals.py +69 -0
- tpyc/sema/literal_utils.py +27 -0
- tpyc/sema/local_deduction.py +1088 -0
- tpyc/sema/macros.py +179 -0
- tpyc/sema/match.py +1177 -0
- tpyc/sema/method_expansion.py +347 -0
- tpyc/sema/methods.py +2197 -0
- tpyc/sema/mutation_propagation.py +268 -0
- tpyc/sema/narrowing.py +857 -0
- tpyc/sema/numeric_lattice.py +160 -0
- tpyc/sema/operators.py +402 -0
- tpyc/sema/overloads.py +841 -0
- tpyc/sema/protocols.py +1209 -0
- tpyc/sema/reach_analysis.py +202 -0
- tpyc/sema/registration.py +3156 -0
- tpyc/sema/scope_tracker.py +193 -0
- tpyc/sema/statements.py +4426 -0
- tpyc/sema/type_ops.py +1879 -0
- tpyc/sema/value_range.py +181 -0
- tpyc/symbol_binding.py +259 -0
- tpyc/test_c3_mro.py +208 -0
- tpyc/test_cli_argv.py +52 -0
- tpyc/test_compiler.py +559 -0
- tpyc/test_contains_type_param.py +101 -0
- tpyc/test_cycle_detection.py +221 -0
- tpyc/test_dump_types.py +225 -0
- tpyc/test_install_docs.py +65 -0
- tpyc/test_local_cpp_form.py +135 -0
- tpyc/test_macro_loader.py +76 -0
- tpyc/test_method_expansion.py +254 -0
- tpyc/test_nominal_identity.py +182 -0
- tpyc/test_overloads.py +410 -0
- tpyc/test_parse.py +303 -0
- tpyc/test_parse_type_ref.py +506 -0
- tpyc/test_parse_version_info.py +58 -0
- tpyc/test_reach_analysis.py +72 -0
- tpyc/test_ref_type.py +216 -0
- tpyc/test_send_sync_substitution.py +276 -0
- tpyc/test_tuple_mutation_propagation.py +206 -0
- tpyc/test_type_def_registry.py +1729 -0
- tpyc/test_union_types.py +195 -0
- tpyc/type_def_registry.py +975 -0
- tpyc/typesys.py +5104 -0
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TurboPython Runtime - UninitHeapStorage
|
|
3
|
+
*
|
|
4
|
+
* Heap-allocated uninitialized storage for T elements.
|
|
5
|
+
* Allocates raw memory for `capacity` elements via ::operator new.
|
|
6
|
+
* Caller is responsible for managing element lifetimes via
|
|
7
|
+
* construct() / destroy().
|
|
8
|
+
*
|
|
9
|
+
* Non-copyable but movable: copy would alias heap memory, move transfers ownership.
|
|
10
|
+
* To grow: allocate new storage, move elements over, destroy old, move-assign.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
#pragma once
|
|
14
|
+
|
|
15
|
+
#include <cstddef>
|
|
16
|
+
#include <cstdint>
|
|
17
|
+
#include <cstring>
|
|
18
|
+
#include <new>
|
|
19
|
+
#include <span>
|
|
20
|
+
#include <type_traits>
|
|
21
|
+
#include <utility>
|
|
22
|
+
|
|
23
|
+
#include "core.hpp"
|
|
24
|
+
|
|
25
|
+
#ifndef NDEBUG
|
|
26
|
+
#include <vector>
|
|
27
|
+
#endif
|
|
28
|
+
|
|
29
|
+
namespace tpy {
|
|
30
|
+
|
|
31
|
+
template <typename T>
|
|
32
|
+
class UninitHeapStorage {
|
|
33
|
+
public:
|
|
34
|
+
UninitHeapStorage(uint32_t capacity)
|
|
35
|
+
: data_(static_cast<T*>(::operator new(sizeof(T) * capacity, std::align_val_t(alignof(T)))))
|
|
36
|
+
, capacity_(capacity)
|
|
37
|
+
#ifndef NDEBUG
|
|
38
|
+
, alive_(capacity, false)
|
|
39
|
+
#endif
|
|
40
|
+
{}
|
|
41
|
+
|
|
42
|
+
~UninitHeapStorage() {
|
|
43
|
+
#ifndef NDEBUG
|
|
44
|
+
for (std::size_t i = 0; i < capacity_; ++i) {
|
|
45
|
+
if (alive_[i]) {
|
|
46
|
+
tpy_panic("UninitHeapStorage destroyed with live elements");
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
#endif
|
|
50
|
+
if (data_) {
|
|
51
|
+
::operator delete(data_, std::align_val_t(alignof(T)));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Non-copyable
|
|
56
|
+
UninitHeapStorage(const UninitHeapStorage&) = delete;
|
|
57
|
+
UninitHeapStorage& operator=(const UninitHeapStorage&) = delete;
|
|
58
|
+
|
|
59
|
+
// Movable (transfers ownership, source becomes empty)
|
|
60
|
+
UninitHeapStorage(UninitHeapStorage&& other) noexcept
|
|
61
|
+
: data_(other.data_)
|
|
62
|
+
, capacity_(other.capacity_)
|
|
63
|
+
#ifndef NDEBUG
|
|
64
|
+
, alive_(std::move(other.alive_))
|
|
65
|
+
#endif
|
|
66
|
+
{
|
|
67
|
+
other.data_ = nullptr;
|
|
68
|
+
other.capacity_ = 0;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
UninitHeapStorage& operator=(UninitHeapStorage&& other) noexcept {
|
|
72
|
+
if (this != &other) {
|
|
73
|
+
#ifndef NDEBUG
|
|
74
|
+
for (std::size_t i = 0; i < capacity_; ++i) {
|
|
75
|
+
if (alive_[i]) {
|
|
76
|
+
tpy_panic("UninitHeapStorage move-assigned with live elements");
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
#endif
|
|
80
|
+
if (data_) {
|
|
81
|
+
::operator delete(data_, std::align_val_t(alignof(T)));
|
|
82
|
+
}
|
|
83
|
+
data_ = other.data_;
|
|
84
|
+
capacity_ = other.capacity_;
|
|
85
|
+
#ifndef NDEBUG
|
|
86
|
+
alive_ = std::move(other.alive_);
|
|
87
|
+
#endif
|
|
88
|
+
other.data_ = nullptr;
|
|
89
|
+
other.capacity_ = 0;
|
|
90
|
+
}
|
|
91
|
+
return *this;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
void init(uint32_t i, T&& value) {
|
|
95
|
+
#ifndef NDEBUG
|
|
96
|
+
if (i >= capacity_) {
|
|
97
|
+
tpy_panic("UninitHeapStorage::init index out of bounds");
|
|
98
|
+
}
|
|
99
|
+
if (alive_[i]) {
|
|
100
|
+
tpy_panic("UninitHeapStorage::init on already-alive slot");
|
|
101
|
+
}
|
|
102
|
+
alive_[i] = true;
|
|
103
|
+
#endif
|
|
104
|
+
::new (static_cast<void*>(&data_[i])) T(std::move(value));
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
void init(uint32_t i, const T& value) {
|
|
108
|
+
#ifndef NDEBUG
|
|
109
|
+
if (i >= capacity_) {
|
|
110
|
+
tpy_panic("UninitHeapStorage::init index out of bounds");
|
|
111
|
+
}
|
|
112
|
+
if (alive_[i]) {
|
|
113
|
+
tpy_panic("UninitHeapStorage::init on already-alive slot");
|
|
114
|
+
}
|
|
115
|
+
alive_[i] = true;
|
|
116
|
+
#endif
|
|
117
|
+
::new (static_cast<void*>(&data_[i])) T(value);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
void init0(T&& value) { init(0, std::move(value)); }
|
|
121
|
+
void init0(const T& value) { init(0, value); }
|
|
122
|
+
|
|
123
|
+
void drop(uint32_t i) {
|
|
124
|
+
#ifndef NDEBUG
|
|
125
|
+
if (i >= capacity_) {
|
|
126
|
+
tpy_panic("UninitHeapStorage::drop index out of bounds");
|
|
127
|
+
}
|
|
128
|
+
if (!alive_[i]) {
|
|
129
|
+
tpy_panic("UninitHeapStorage::drop on dead slot");
|
|
130
|
+
}
|
|
131
|
+
alive_[i] = false;
|
|
132
|
+
#endif
|
|
133
|
+
data_[i].~T();
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
void drop0() { drop(0); }
|
|
137
|
+
|
|
138
|
+
T& load(uint32_t i) {
|
|
139
|
+
#ifndef NDEBUG
|
|
140
|
+
if (i >= capacity_) {
|
|
141
|
+
tpy_panic("UninitHeapStorage::load index out of bounds");
|
|
142
|
+
}
|
|
143
|
+
if (!alive_[i]) {
|
|
144
|
+
tpy_panic("UninitHeapStorage::load on dead slot");
|
|
145
|
+
}
|
|
146
|
+
#endif
|
|
147
|
+
return data_[i];
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const T& load(uint32_t i) const {
|
|
151
|
+
#ifndef NDEBUG
|
|
152
|
+
if (i >= capacity_) {
|
|
153
|
+
tpy_panic("UninitHeapStorage::load index out of bounds");
|
|
154
|
+
}
|
|
155
|
+
if (!alive_[i]) {
|
|
156
|
+
tpy_panic("UninitHeapStorage::load on dead slot");
|
|
157
|
+
}
|
|
158
|
+
#endif
|
|
159
|
+
return data_[i];
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
T& load0() { return load(0); }
|
|
163
|
+
const T& load0() const { return load(0); }
|
|
164
|
+
|
|
165
|
+
T take(uint32_t i) {
|
|
166
|
+
#ifndef NDEBUG
|
|
167
|
+
if (i >= capacity_) {
|
|
168
|
+
tpy_panic("UninitHeapStorage::take index out of bounds");
|
|
169
|
+
}
|
|
170
|
+
if (!alive_[i]) {
|
|
171
|
+
tpy_panic("UninitHeapStorage::take on dead slot");
|
|
172
|
+
}
|
|
173
|
+
alive_[i] = false;
|
|
174
|
+
#endif
|
|
175
|
+
T result = std::move(data_[i]);
|
|
176
|
+
data_[i].~T();
|
|
177
|
+
return result;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
T take0() { return take(0); }
|
|
181
|
+
|
|
182
|
+
T* ptr() { return data_; }
|
|
183
|
+
const T* ptr() const { return data_; }
|
|
184
|
+
|
|
185
|
+
uint32_t capacity() const { return capacity_; }
|
|
186
|
+
|
|
187
|
+
void init_from_span(uint32_t start, std::span<const T> src) {
|
|
188
|
+
#ifndef NDEBUG
|
|
189
|
+
if (start + src.size() > capacity_) {
|
|
190
|
+
tpy_panic("UninitHeapStorage::init_from_span: span exceeds capacity");
|
|
191
|
+
}
|
|
192
|
+
for (std::size_t i = 0; i < src.size(); ++i) {
|
|
193
|
+
if (alive_[start + i]) {
|
|
194
|
+
tpy_panic("UninitHeapStorage::init_from_span on already-alive slot");
|
|
195
|
+
}
|
|
196
|
+
alive_[start + i] = true;
|
|
197
|
+
}
|
|
198
|
+
#endif
|
|
199
|
+
if constexpr (std::is_trivially_copyable_v<T>) {
|
|
200
|
+
std::memcpy(static_cast<void*>(&data_[start]), src.data(), src.size() * sizeof(T));
|
|
201
|
+
} else {
|
|
202
|
+
for (std::size_t i = 0; i < src.size(); ++i) {
|
|
203
|
+
::new (static_cast<void*>(&data_[start + i])) T(src[i]);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
void drop_n(uint32_t start, uint32_t count) {
|
|
209
|
+
#ifndef NDEBUG
|
|
210
|
+
for (uint32_t i = 0; i < count; ++i) {
|
|
211
|
+
uint32_t idx = start + i;
|
|
212
|
+
if (idx >= capacity_) {
|
|
213
|
+
tpy_panic("UninitHeapStorage::drop_n index out of bounds");
|
|
214
|
+
}
|
|
215
|
+
if (!alive_[idx]) {
|
|
216
|
+
tpy_panic("UninitHeapStorage::drop_n on dead slot");
|
|
217
|
+
}
|
|
218
|
+
alive_[idx] = false;
|
|
219
|
+
}
|
|
220
|
+
#endif
|
|
221
|
+
if constexpr (!std::is_trivially_destructible_v<T>) {
|
|
222
|
+
for (uint32_t i = 0; i < count; ++i) {
|
|
223
|
+
data_[start + i].~T();
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
void shift(uint32_t src, uint32_t dst, uint32_t count) {
|
|
229
|
+
if (count == 0 || src == dst) return;
|
|
230
|
+
#ifndef NDEBUG
|
|
231
|
+
for (uint32_t i = 0; i < count; ++i) {
|
|
232
|
+
if (src + i >= capacity_ || dst + i >= capacity_) {
|
|
233
|
+
tpy_panic("UninitHeapStorage::shift index out of bounds");
|
|
234
|
+
}
|
|
235
|
+
if (!alive_[src + i]) {
|
|
236
|
+
tpy_panic("UninitHeapStorage::shift on dead source slot");
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
for (uint32_t i = 0; i < count; ++i) {
|
|
240
|
+
alive_[src + i] = false;
|
|
241
|
+
}
|
|
242
|
+
for (uint32_t i = 0; i < count; ++i) {
|
|
243
|
+
alive_[dst + i] = true;
|
|
244
|
+
}
|
|
245
|
+
#endif
|
|
246
|
+
if constexpr (std::is_trivially_copyable_v<T>) {
|
|
247
|
+
std::memmove(static_cast<void*>(&data_[dst]),
|
|
248
|
+
static_cast<const void*>(&data_[src]),
|
|
249
|
+
static_cast<std::size_t>(count) * sizeof(T));
|
|
250
|
+
} else if (dst < src) {
|
|
251
|
+
for (uint32_t i = 0; i < count; ++i) {
|
|
252
|
+
::new (static_cast<void*>(&data_[dst + i]))
|
|
253
|
+
T(std::move(data_[src + i]));
|
|
254
|
+
data_[src + i].~T();
|
|
255
|
+
}
|
|
256
|
+
} else {
|
|
257
|
+
for (uint32_t i = count; i > 0; --i) {
|
|
258
|
+
uint32_t idx = i - 1;
|
|
259
|
+
::new (static_cast<void*>(&data_[dst + idx]))
|
|
260
|
+
T(std::move(data_[src + idx]));
|
|
261
|
+
data_[src + idx].~T();
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// TODO: emplace(i, args...) for perfect-forwarding construction
|
|
267
|
+
|
|
268
|
+
private:
|
|
269
|
+
T* data_;
|
|
270
|
+
uint32_t capacity_;
|
|
271
|
+
|
|
272
|
+
#ifndef NDEBUG
|
|
273
|
+
std::vector<bool> alive_;
|
|
274
|
+
#endif
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
} // namespace tpy
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TurboPython Runtime - varargs<T>
|
|
3
|
+
*
|
|
4
|
+
* Span-like view for *args parameters.
|
|
5
|
+
*
|
|
6
|
+
* Value types (is_value_type_v<T>): thin wrapper around contiguous T storage.
|
|
7
|
+
* No indirection, no branches -- equivalent to std::span<T>.
|
|
8
|
+
*
|
|
9
|
+
* Non-value types: dual-mode view.
|
|
10
|
+
* Direct mode: contiguous T storage (*list unpacking into vector/array).
|
|
11
|
+
* Indirect mode: T* pointer array (individual args packed by address).
|
|
12
|
+
* operator[] returns T& in both modes.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
#pragma once
|
|
16
|
+
|
|
17
|
+
#include "type_traits.hpp"
|
|
18
|
+
|
|
19
|
+
#include <array>
|
|
20
|
+
#include <cstdint>
|
|
21
|
+
#include <span>
|
|
22
|
+
|
|
23
|
+
namespace tpy {
|
|
24
|
+
|
|
25
|
+
// Primary template: non-value types (dual-mode)
|
|
26
|
+
template<typename T, bool IsValue = is_value_type_v<T>>
|
|
27
|
+
struct varargs {
|
|
28
|
+
T* direct_ = nullptr;
|
|
29
|
+
T* const* indirect_ = nullptr;
|
|
30
|
+
int32_t size_ = 0;
|
|
31
|
+
|
|
32
|
+
varargs() = default;
|
|
33
|
+
|
|
34
|
+
// Direct mode: contiguous T storage (*list unpacking)
|
|
35
|
+
varargs(std::span<T> s) : direct_(s.data()), size_(static_cast<int32_t>(s.size())) {}
|
|
36
|
+
|
|
37
|
+
template<size_t N>
|
|
38
|
+
varargs(std::array<T, N>& arr) : direct_(arr.data()), size_(static_cast<int32_t>(N)) {}
|
|
39
|
+
|
|
40
|
+
// Indirect mode: pointer array (individual args)
|
|
41
|
+
template<size_t N>
|
|
42
|
+
varargs(std::array<T*, N>& arr) : indirect_(arr.data()), size_(static_cast<int32_t>(N)) {}
|
|
43
|
+
|
|
44
|
+
// Readonly view of a mutable varargs<U> -- forwarding `*xs` where `xs` is a
|
|
45
|
+
// mutable `*args` param into a `readonly[...]` vararg. Present only when T
|
|
46
|
+
// is const. The pointer-array conversion (`U* const*` -> `const U* const*`,
|
|
47
|
+
// i.e. `T* const*`) is a plain implicit qualification conversion -- legal
|
|
48
|
+
// because the enclosing pointer level is already const -- not a reinterpret.
|
|
49
|
+
template<typename U = T, std::enable_if_t<std::is_const_v<U>, int> = 0>
|
|
50
|
+
varargs(const varargs<std::remove_const_t<U>>& o)
|
|
51
|
+
: direct_(o.direct_),
|
|
52
|
+
indirect_(o.indirect_),
|
|
53
|
+
size_(o.size_) {}
|
|
54
|
+
|
|
55
|
+
T& operator[](int32_t i) const {
|
|
56
|
+
return indirect_ ? *indirect_[i] : direct_[i];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
int32_t size() const { return size_; }
|
|
60
|
+
bool empty() const { return size_ == 0; }
|
|
61
|
+
|
|
62
|
+
// Python-style slice preserving direct-vs-indirect mode. Returns another
|
|
63
|
+
// varargs of the same instantiation with adjusted pointers + size -- the
|
|
64
|
+
// only correct shape, since indirect-mode storage (`T* const*`) cannot be
|
|
65
|
+
// exposed as `std::span<T>`. Indices follow Python clamp semantics.
|
|
66
|
+
varargs slice(int32_t start, int32_t stop) const {
|
|
67
|
+
int32_t i = start;
|
|
68
|
+
int32_t j = stop;
|
|
69
|
+
if (i < 0) i += size_;
|
|
70
|
+
if (j < 0) j += size_;
|
|
71
|
+
if (i < 0) i = 0;
|
|
72
|
+
if (j < 0) j = 0;
|
|
73
|
+
if (i > size_) i = size_;
|
|
74
|
+
if (j > size_) j = size_;
|
|
75
|
+
varargs r;
|
|
76
|
+
if (i >= j) return r;
|
|
77
|
+
r.size_ = j - i;
|
|
78
|
+
if (direct_) r.direct_ = direct_ + i;
|
|
79
|
+
if (indirect_) r.indirect_ = indirect_ + i;
|
|
80
|
+
return r;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
struct iterator {
|
|
84
|
+
T* direct_;
|
|
85
|
+
T* const* indirect_;
|
|
86
|
+
|
|
87
|
+
T& operator*() const { return indirect_ ? **indirect_ : *direct_; }
|
|
88
|
+
|
|
89
|
+
iterator& operator++() {
|
|
90
|
+
if (indirect_) ++indirect_; else ++direct_;
|
|
91
|
+
return *this;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
bool operator==(const iterator& o) const {
|
|
95
|
+
return indirect_ ? indirect_ == o.indirect_ : direct_ == o.direct_;
|
|
96
|
+
}
|
|
97
|
+
bool operator!=(const iterator& o) const { return !(*this == o); }
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
iterator begin() const { return {direct_, indirect_}; }
|
|
101
|
+
iterator end() const {
|
|
102
|
+
return {direct_ ? direct_ + size_ : nullptr,
|
|
103
|
+
indirect_ ? indirect_ + size_ : nullptr};
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
// Value type specialization: direct only, no indirection overhead
|
|
108
|
+
template<typename T>
|
|
109
|
+
struct varargs<T, true> {
|
|
110
|
+
T* data_ = nullptr;
|
|
111
|
+
int32_t size_ = 0;
|
|
112
|
+
|
|
113
|
+
varargs() = default;
|
|
114
|
+
|
|
115
|
+
varargs(std::span<T> s) : data_(s.data()), size_(static_cast<int32_t>(s.size())) {}
|
|
116
|
+
|
|
117
|
+
template<size_t N>
|
|
118
|
+
varargs(std::array<T, N>& arr) : data_(arr.data()), size_(static_cast<int32_t>(N)) {}
|
|
119
|
+
|
|
120
|
+
// Readonly view of a mutable value-type varargs<U> (forwarding into a
|
|
121
|
+
// `readonly[...]` value-type vararg). Present only when T is const.
|
|
122
|
+
template<typename U = T, std::enable_if_t<std::is_const_v<U>, int> = 0>
|
|
123
|
+
varargs(const varargs<std::remove_const_t<U>>& o)
|
|
124
|
+
: data_(o.data_), size_(o.size_) {}
|
|
125
|
+
|
|
126
|
+
T& operator[](int32_t i) const { return data_[i]; }
|
|
127
|
+
int32_t size() const { return size_; }
|
|
128
|
+
bool empty() const { return size_ == 0; }
|
|
129
|
+
T* data() const { return data_; }
|
|
130
|
+
|
|
131
|
+
using iterator = T*;
|
|
132
|
+
T* begin() const { return data_; }
|
|
133
|
+
T* end() const { return data_ + size_; }
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
template<typename T, bool V>
|
|
137
|
+
int32_t __len__(const varargs<T, V>& v) { return v.size(); }
|
|
138
|
+
|
|
139
|
+
template<typename T, bool V>
|
|
140
|
+
T& __getitem__(const varargs<T, V>& v, int32_t i) { return v[i]; }
|
|
141
|
+
|
|
142
|
+
} // namespace tpy
|
|
143
|
+
|
|
144
|
+
#include "container_ops.hpp"
|
|
145
|
+
|
|
146
|
+
namespace tpy {
|
|
147
|
+
|
|
148
|
+
// list_slice on a non-value varargs returns another varargs (preserving
|
|
149
|
+
// direct-vs-indirect mode), not std::span<T> -- the generic Container
|
|
150
|
+
// list_slice in container_ops.hpp would call `c.data()` which non-value
|
|
151
|
+
// varargs intentionally doesn't expose (indirect storage is `T* const*`,
|
|
152
|
+
// not contiguous T). The value-type varargs path stays on the generic
|
|
153
|
+
// template via its own `data()` (defined in the value-type specialization).
|
|
154
|
+
template<typename T>
|
|
155
|
+
varargs<T, false> list_slice(varargs<T, false>& c, int32_t start, int32_t stop) {
|
|
156
|
+
return c.slice(start, stop);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
template<typename T>
|
|
160
|
+
varargs<T, false> list_slice(const varargs<T, false>& c, int32_t start, int32_t stop) {
|
|
161
|
+
return c.slice(start, stop);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
template<typename T>
|
|
165
|
+
varargs<T, false> list_slice(varargs<T, false>& c, BasicSlice sl) {
|
|
166
|
+
return c.slice(sl.start.value_or(0), sl.stop.value_or(SLICE_END));
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
template<typename T>
|
|
170
|
+
varargs<T, false> list_slice(const varargs<T, false>& c, BasicSlice sl) {
|
|
171
|
+
return c.slice(sl.start.value_or(0), sl.stop.value_or(SLICE_END));
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
} // namespace tpy
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pointer-variant utilities for non-value union types.
|
|
3
|
+
*
|
|
4
|
+
* Non-value unions (e.g. Dog | Cat where members are records) use a two-layer
|
|
5
|
+
* representation:
|
|
6
|
+
* - Storage: std::variant<Dog, Cat> (owns values)
|
|
7
|
+
* - Reference: std::variant<Dog*, Cat*> (borrows values)
|
|
8
|
+
*
|
|
9
|
+
* to_ptr_variant() converts a storage variant reference into a pointer variant.
|
|
10
|
+
* std::monostate members (representing None in nullable unions) pass through.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
#pragma once
|
|
14
|
+
|
|
15
|
+
#include <variant>
|
|
16
|
+
#include <type_traits>
|
|
17
|
+
|
|
18
|
+
namespace tpy {
|
|
19
|
+
|
|
20
|
+
namespace detail {
|
|
21
|
+
|
|
22
|
+
// Map T -> T*, but monostate -> monostate
|
|
23
|
+
template<typename T>
|
|
24
|
+
struct ptr_of { using type = T*; };
|
|
25
|
+
|
|
26
|
+
template<>
|
|
27
|
+
struct ptr_of<std::monostate> { using type = std::monostate; };
|
|
28
|
+
|
|
29
|
+
// Map T -> const T*, but monostate -> monostate
|
|
30
|
+
template<typename T>
|
|
31
|
+
struct const_ptr_of { using type = const T*; };
|
|
32
|
+
|
|
33
|
+
template<>
|
|
34
|
+
struct const_ptr_of<std::monostate> { using type = std::monostate; };
|
|
35
|
+
|
|
36
|
+
// Try to convert alternative I: if active, emplace pointer into result.
|
|
37
|
+
// Returns true (short-circuits fold) on match.
|
|
38
|
+
template<std::size_t I, typename Result, typename Variant>
|
|
39
|
+
bool try_emplace_ptr(Result& r, Variant& v) {
|
|
40
|
+
if (v.index() != I) return false;
|
|
41
|
+
using Alt = std::variant_alternative_t<I, std::remove_cvref_t<Variant>>;
|
|
42
|
+
if constexpr (std::is_same_v<Alt, std::monostate>) {
|
|
43
|
+
r.template emplace<I>(std::monostate{});
|
|
44
|
+
} else {
|
|
45
|
+
r.template emplace<I>(&std::get<I>(v));
|
|
46
|
+
}
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
template<typename Result, typename Variant, std::size_t... Is>
|
|
51
|
+
Result to_ptr_variant_impl(Variant& v, std::index_sequence<Is...>) {
|
|
52
|
+
Result r;
|
|
53
|
+
(try_emplace_ptr<Is>(r, v) || ...);
|
|
54
|
+
return r;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
} // namespace detail
|
|
58
|
+
|
|
59
|
+
// Convert std::variant<Ts...>& -> std::variant<Ts*...> (monostate passthrough)
|
|
60
|
+
template<typename... Ts>
|
|
61
|
+
std::variant<typename detail::ptr_of<Ts>::type...>
|
|
62
|
+
to_ptr_variant(std::variant<Ts...>& v) {
|
|
63
|
+
using Result = std::variant<typename detail::ptr_of<Ts>::type...>;
|
|
64
|
+
return detail::to_ptr_variant_impl<Result>(v, std::index_sequence_for<Ts...>{});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Convert const std::variant<Ts...>& -> std::variant<const Ts*...> (monostate passthrough)
|
|
68
|
+
template<typename... Ts>
|
|
69
|
+
std::variant<typename detail::const_ptr_of<Ts>::type...>
|
|
70
|
+
to_const_ptr_variant(const std::variant<Ts...>& v) {
|
|
71
|
+
using Result = std::variant<typename detail::const_ptr_of<Ts>::type...>;
|
|
72
|
+
return detail::to_ptr_variant_impl<Result>(v, std::index_sequence_for<Ts...>{});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Convert mutable pointer variant to const pointer variant:
|
|
76
|
+
// std::variant<T*...> -> std::variant<const T*...>
|
|
77
|
+
// Handles monostate (nullable unions) by passing it through.
|
|
78
|
+
namespace detail {
|
|
79
|
+
template<typename Result>
|
|
80
|
+
struct to_const_visitor {
|
|
81
|
+
template<typename T>
|
|
82
|
+
Result operator()(T* p) const { return static_cast<const T*>(p); }
|
|
83
|
+
Result operator()(std::monostate m) const { return m; }
|
|
84
|
+
};
|
|
85
|
+
} // namespace detail
|
|
86
|
+
|
|
87
|
+
template<typename Result, typename... Alts>
|
|
88
|
+
Result ptr_variant_to_const(const std::variant<Alts...>& v) {
|
|
89
|
+
return std::visit(detail::to_const_visitor<Result>{}, v);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Reverse: convert pointer variant to value variant (copies active member).
|
|
93
|
+
// Used when storing into fields/containers that own their values.
|
|
94
|
+
// ValueVariant = target type (e.g. std::variant<Dog, Cat>)
|
|
95
|
+
// PtrVariant = source type (e.g. std::variant<Dog*, Cat*>)
|
|
96
|
+
namespace detail {
|
|
97
|
+
|
|
98
|
+
// Visitor that converts each pointer alternative to its value type.
|
|
99
|
+
// Constructs the Result variant directly, avoiding default-construction
|
|
100
|
+
// (which would require the first alternative to be default-constructible).
|
|
101
|
+
template<typename Result>
|
|
102
|
+
struct deref_visitor {
|
|
103
|
+
template<typename T>
|
|
104
|
+
Result operator()(T* p) const { return Result{*p}; }
|
|
105
|
+
|
|
106
|
+
Result operator()(std::monostate) const { return Result{std::monostate{}}; }
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
} // namespace detail
|
|
110
|
+
|
|
111
|
+
// Convert pointer variant to value variant: to_value_variant<std::variant<Dog,Cat>>(pv)
|
|
112
|
+
// Caller must specify the target value-variant type explicitly.
|
|
113
|
+
template<typename ValueVariant, typename... PtrAlts>
|
|
114
|
+
ValueVariant to_value_variant(const std::variant<PtrAlts...>& v) {
|
|
115
|
+
return std::visit(detail::deref_visitor<ValueVariant>{}, v);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
} // namespace tpy
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
// Out-of-line helpers for TPy's `socket` stdlib module.
|
|
2
|
+
//
|
|
3
|
+
// Exists because:
|
|
4
|
+
// * struct addrinfo's field order is not portable across Linux and
|
|
5
|
+
// BSD/macOS (ai_addr and ai_canonname are swapped). Declaring it at
|
|
6
|
+
// @native(binding="C") level would only work on one platform family.
|
|
7
|
+
// tpy_resolve_ipv4 walks the list here and hands back a flat 4-byte
|
|
8
|
+
// IPv4 address.
|
|
9
|
+
// * `errno` and gai_strerror need `<errno.h>` / `<netdb.h>`, whose
|
|
10
|
+
// macros we keep out of every TPy-generated TU by hiding them
|
|
11
|
+
// behind these helpers.
|
|
12
|
+
//
|
|
13
|
+
// Everything else in the socket module binds libc directly via @native
|
|
14
|
+
// against the forward decls in runtime/cpp/include/tpy/stdlib/socket_h.hpp.
|
|
15
|
+
//
|
|
16
|
+
// We intentionally do NOT `#include` socket_h.hpp here: its libc forward
|
|
17
|
+
// decls (using `void*` sockaddr pointers, no `noexcept`) conflict with
|
|
18
|
+
// the real libc decls the system headers bring in. ABI consistency for
|
|
19
|
+
// the three `tpy_*` symbols is maintained manually -- trivial with three
|
|
20
|
+
// short signatures, and the only alternative is duplicating two parallel
|
|
21
|
+
// header variants.
|
|
22
|
+
|
|
23
|
+
#include <cerrno>
|
|
24
|
+
#include <cstdint>
|
|
25
|
+
#include <cstring>
|
|
26
|
+
#include <string>
|
|
27
|
+
|
|
28
|
+
#include <sys/socket.h>
|
|
29
|
+
#include <netinet/in.h>
|
|
30
|
+
#include <netdb.h>
|
|
31
|
+
|
|
32
|
+
namespace {
|
|
33
|
+
|
|
34
|
+
// Thread-local so two threads running concurrent resolves don't stomp
|
|
35
|
+
// each other's error messages. The buffer is a fixed size because
|
|
36
|
+
// gai_strerror / strerror messages are short; we copy to decouple the
|
|
37
|
+
// returned pointer from libc's internal buffer reuse.
|
|
38
|
+
thread_local char g_resolve_err[256] = {0};
|
|
39
|
+
|
|
40
|
+
void set_resolve_error(const char* msg) {
|
|
41
|
+
if (msg == nullptr) {
|
|
42
|
+
g_resolve_err[0] = '\0';
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
std::strncpy(g_resolve_err, msg, sizeof(g_resolve_err) - 1);
|
|
46
|
+
g_resolve_err[sizeof(g_resolve_err) - 1] = '\0';
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
} // namespace
|
|
50
|
+
|
|
51
|
+
extern "C" {
|
|
52
|
+
|
|
53
|
+
int tpy_resolve_ipv4(const std::uint8_t* host, std::uint64_t host_len,
|
|
54
|
+
std::uint8_t out[4]) {
|
|
55
|
+
// getaddrinfo requires a null-terminated C string. TPy `str` is
|
|
56
|
+
// std::string_view -- not guaranteed terminated -- so copy into a
|
|
57
|
+
// local std::string. reinterpret_cast<const char*> because TPy
|
|
58
|
+
// binding types string bytes as uint8_t* but std::string takes char*;
|
|
59
|
+
// the underlying bytes are identical.
|
|
60
|
+
std::string host_s(reinterpret_cast<const char*>(host), host_len);
|
|
61
|
+
|
|
62
|
+
addrinfo hints{};
|
|
63
|
+
hints.ai_family = AF_INET;
|
|
64
|
+
hints.ai_socktype = SOCK_STREAM;
|
|
65
|
+
|
|
66
|
+
addrinfo* res = nullptr;
|
|
67
|
+
int rc = getaddrinfo(host_s.c_str(), nullptr, &hints, &res);
|
|
68
|
+
if (rc != 0) {
|
|
69
|
+
set_resolve_error(gai_strerror(rc));
|
|
70
|
+
return -1;
|
|
71
|
+
}
|
|
72
|
+
if (res == nullptr) {
|
|
73
|
+
// getaddrinfo returned 0 but no results -- shouldn't happen,
|
|
74
|
+
// but guard anyway.
|
|
75
|
+
set_resolve_error("no addresses returned");
|
|
76
|
+
return -1;
|
|
77
|
+
}
|
|
78
|
+
if (res->ai_addr == nullptr) {
|
|
79
|
+
// Defensive: with AF_INET + SOCK_STREAM hints every returned
|
|
80
|
+
// entry should carry a sockaddr_in in ai_addr. A broken or
|
|
81
|
+
// custom resolver library could in theory break this
|
|
82
|
+
// invariant; fail cleanly rather than dereference null.
|
|
83
|
+
freeaddrinfo(res);
|
|
84
|
+
set_resolve_error("getaddrinfo returned entry with null ai_addr");
|
|
85
|
+
return -1;
|
|
86
|
+
}
|
|
87
|
+
// Copy the first A-record's 4 bytes. `sin_addr.s_addr` is already in
|
|
88
|
+
// network byte order, which is what the caller wants for sockaddr_in.
|
|
89
|
+
auto* sin = reinterpret_cast<sockaddr_in*>(res->ai_addr);
|
|
90
|
+
std::memcpy(out, &sin->sin_addr, 4);
|
|
91
|
+
freeaddrinfo(res);
|
|
92
|
+
set_resolve_error(nullptr);
|
|
93
|
+
return 0;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
int tpy_errno() {
|
|
97
|
+
return errno;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const char* tpy_last_resolve_error() {
|
|
101
|
+
return g_resolve_err;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
} // extern "C"
|