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,487 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TurboPython Runtime - Container Operations
|
|
3
|
+
*
|
|
4
|
+
* Helper functions for containers: index normalization, element access,
|
|
5
|
+
* and list methods (insert, remove, extend, etc.).
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#include <algorithm>
|
|
11
|
+
#include <array>
|
|
12
|
+
#include <cstddef>
|
|
13
|
+
#include <cstdint>
|
|
14
|
+
#include <format>
|
|
15
|
+
#include <initializer_list>
|
|
16
|
+
#include <ranges>
|
|
17
|
+
#include <span>
|
|
18
|
+
#include <string_view>
|
|
19
|
+
#include <utility>
|
|
20
|
+
#include <vector>
|
|
21
|
+
|
|
22
|
+
#include "core.hpp"
|
|
23
|
+
#include "slice.hpp"
|
|
24
|
+
#include "type_traits.hpp"
|
|
25
|
+
|
|
26
|
+
namespace tpy {
|
|
27
|
+
|
|
28
|
+
/// Sentinel for omitted slice upper bound.
|
|
29
|
+
inline constexpr int32_t SLICE_END = INT32_MAX;
|
|
30
|
+
/// Sentinel for omitted slice bound in stepped slicing (distinct from SLICE_END
|
|
31
|
+
/// because stepped slicing needs to distinguish None from 0 -- negative step
|
|
32
|
+
/// reverses the default start/stop direction).
|
|
33
|
+
/// Note: collides with INT32_MIN as a valid Int32 value. In practice this is
|
|
34
|
+
/// harmless -- no container can have 2^31 elements, so the clamped result is
|
|
35
|
+
/// identical whether the bound is treated as "absent" or as -2147483648.
|
|
36
|
+
inline constexpr int32_t SLICE_NONE = INT32_MIN;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* normalize_index - Convert Python-style index to size_t.
|
|
40
|
+
*
|
|
41
|
+
* Supports negative indexing: -1 is last element, -2 is second-to-last, etc.
|
|
42
|
+
* Throws IndexError if index is out of bounds.
|
|
43
|
+
*/
|
|
44
|
+
template <typename Container>
|
|
45
|
+
std::size_t normalize_index(const Container& c, int32_t index, const char* context) {
|
|
46
|
+
std::ptrdiff_t i = index;
|
|
47
|
+
if (i < 0) {
|
|
48
|
+
i += static_cast<std::ptrdiff_t>(c.size());
|
|
49
|
+
}
|
|
50
|
+
if (i < 0 || static_cast<std::size_t>(i) >= c.size()) {
|
|
51
|
+
raise_index_error(context);
|
|
52
|
+
}
|
|
53
|
+
return static_cast<std::size_t>(i);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* pop_back - Python list.pop() equivalent for std::vector.
|
|
58
|
+
*
|
|
59
|
+
* Removes and returns the last element. Throws IndexError if vector is empty.
|
|
60
|
+
*/
|
|
61
|
+
template <typename T>
|
|
62
|
+
T pop_back(std::vector<T>& v) {
|
|
63
|
+
if (v.empty()) {
|
|
64
|
+
raise_index_error("pop from empty list");
|
|
65
|
+
}
|
|
66
|
+
T result = std::move(v.back());
|
|
67
|
+
v.pop_back();
|
|
68
|
+
return result;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* str_slice - Python-style string slicing with clamping semantics.
|
|
73
|
+
*
|
|
74
|
+
* Unlike single-index access, slicing does NOT panic on out-of-bounds:
|
|
75
|
+
* indices are clamped to [0, len]. Negative indices are normalized first.
|
|
76
|
+
* Bounds are int32_t; codegen uses tpy::SLICE_END as sentinel for omitted
|
|
77
|
+
* upper bound, so slicing is correct for strings up to ~2GB.
|
|
78
|
+
*/
|
|
79
|
+
inline std::string_view str_slice(std::string_view s, int32_t start, int32_t stop) {
|
|
80
|
+
auto len = static_cast<std::ptrdiff_t>(s.size());
|
|
81
|
+
std::ptrdiff_t i = start;
|
|
82
|
+
std::ptrdiff_t j = stop;
|
|
83
|
+
if (i < 0) i += len;
|
|
84
|
+
if (j < 0) j += len;
|
|
85
|
+
i = std::clamp(i, std::ptrdiff_t{0}, len);
|
|
86
|
+
j = std::clamp(j, std::ptrdiff_t{0}, len);
|
|
87
|
+
if (i >= j) return {};
|
|
88
|
+
return s.substr(static_cast<std::size_t>(i), static_cast<std::size_t>(j - i));
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/// BasicSlice overload: unpacks start/stop from the slice object.
|
|
92
|
+
inline std::string_view str_slice(std::string_view s, BasicSlice sl) {
|
|
93
|
+
return str_slice(s, sl.start.value_or(0), sl.stop.value_or(SLICE_END));
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* list_slice - Python-style container slicing: items[start:stop].
|
|
98
|
+
*
|
|
99
|
+
* Returns a std::span view into the container. Indices are clamped, never panics.
|
|
100
|
+
* Const containers or span<const T> yield span<const T>, mutable yield span<T>.
|
|
101
|
+
* Omitted bounds use tpy::SLICE_END/0 as sentinels. Correct for containers up to ~2B elements.
|
|
102
|
+
*/
|
|
103
|
+
template <typename Container>
|
|
104
|
+
auto list_slice(Container&& c, int32_t start, int32_t stop) {
|
|
105
|
+
using ElemRef = std::remove_pointer_t<decltype(c.data())>;
|
|
106
|
+
using T = std::remove_const_t<ElemRef>;
|
|
107
|
+
using SpanT = std::conditional_t<std::is_const_v<ElemRef>, std::span<const T>, std::span<T>>;
|
|
108
|
+
auto len = static_cast<std::ptrdiff_t>(c.size());
|
|
109
|
+
std::ptrdiff_t i = start;
|
|
110
|
+
std::ptrdiff_t j = stop;
|
|
111
|
+
if (i < 0) i += len;
|
|
112
|
+
if (j < 0) j += len;
|
|
113
|
+
i = std::clamp(i, std::ptrdiff_t{0}, len);
|
|
114
|
+
j = std::clamp(j, std::ptrdiff_t{0}, len);
|
|
115
|
+
if (i >= j) return SpanT{};
|
|
116
|
+
return SpanT{c.data() + i, static_cast<std::size_t>(j - i)};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/// BasicSlice overload: unpacks start/stop from the slice object.
|
|
120
|
+
template <typename Container>
|
|
121
|
+
auto list_slice(Container&& c, BasicSlice sl) {
|
|
122
|
+
return list_slice(std::forward<Container>(c),
|
|
123
|
+
sl.start.value_or(0), sl.stop.value_or(SLICE_END));
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* list_set_slice - Python-style slice assignment: items[start:stop] = values.
|
|
128
|
+
* Replaces elements [start, stop) with values. Can resize the vector.
|
|
129
|
+
* Indices are clamped (Python semantics).
|
|
130
|
+
*/
|
|
131
|
+
template<typename T, typename Range>
|
|
132
|
+
requires std::ranges::input_range<const Range>
|
|
133
|
+
void list_set_slice(std::vector<T>& vec, int32_t start, int32_t stop, const Range& values) {
|
|
134
|
+
auto len = static_cast<std::ptrdiff_t>(vec.size());
|
|
135
|
+
std::ptrdiff_t i = start, j = stop;
|
|
136
|
+
if (i < 0) i += len;
|
|
137
|
+
if (j < 0) j += len;
|
|
138
|
+
i = std::clamp(i, std::ptrdiff_t{0}, len);
|
|
139
|
+
j = std::clamp(j, std::ptrdiff_t{0}, len);
|
|
140
|
+
// Clamp reversed range to empty insertion (matches Python: a[5:2] = [...] inserts at 5)
|
|
141
|
+
if (j < i) j = i;
|
|
142
|
+
// Guard against self-aliasing (e.g. a[1:3] = a): erase invalidates iterators into vec
|
|
143
|
+
if constexpr (std::is_same_v<std::decay_t<Range>, std::vector<T>>) {
|
|
144
|
+
if (&values == &vec) {
|
|
145
|
+
std::vector<T> copy = values;
|
|
146
|
+
vec.erase(vec.begin() + i, vec.begin() + j);
|
|
147
|
+
vec.insert(vec.begin() + i, copy.begin(), copy.end());
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
vec.erase(vec.begin() + i, vec.begin() + j);
|
|
152
|
+
vec.insert(vec.begin() + i, values.begin(), values.end());
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/// BasicSlice overload: unpacks start/stop from the slice object.
|
|
156
|
+
template<typename T, typename Range>
|
|
157
|
+
requires std::ranges::input_range<const Range>
|
|
158
|
+
void list_set_slice(std::vector<T>& vec, BasicSlice sl, const Range& values) {
|
|
159
|
+
list_set_slice(vec, sl.start.value_or(0), sl.stop.value_or(SLICE_END), values);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// =============================================
|
|
163
|
+
// Stepped slice helpers (a[start:stop:step])
|
|
164
|
+
// =============================================
|
|
165
|
+
|
|
166
|
+
namespace detail {
|
|
167
|
+
|
|
168
|
+
/// Resolve SLICE_NONE bounds for stepped slicing. When step > 0, default
|
|
169
|
+
/// start is 0 and default stop is len. When step < 0, default start is
|
|
170
|
+
/// len-1 and default stop is -(len+1) (i.e., one before the beginning).
|
|
171
|
+
struct SteppedSliceBounds {
|
|
172
|
+
std::ptrdiff_t start;
|
|
173
|
+
std::ptrdiff_t stop;
|
|
174
|
+
std::ptrdiff_t step;
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
inline SteppedSliceBounds resolve_stepped_bounds(
|
|
178
|
+
int32_t raw_start, int32_t raw_stop, int32_t raw_step,
|
|
179
|
+
std::ptrdiff_t len) {
|
|
180
|
+
if (raw_step == 0) raise_value_error("slice step cannot be zero");
|
|
181
|
+
auto step = static_cast<std::ptrdiff_t>(raw_step);
|
|
182
|
+
std::ptrdiff_t start, stop;
|
|
183
|
+
if (raw_start == SLICE_NONE) {
|
|
184
|
+
start = (step > 0) ? 0 : len - 1;
|
|
185
|
+
} else {
|
|
186
|
+
start = raw_start;
|
|
187
|
+
if (start < 0) start += len;
|
|
188
|
+
// Positive step: clamp to [0, len]. Negative step: clamp to [-1, len-1]
|
|
189
|
+
// (start=-1 means "before the beginning" -> empty result).
|
|
190
|
+
start = std::clamp(start,
|
|
191
|
+
(step > 0) ? std::ptrdiff_t{0} : std::ptrdiff_t{-1},
|
|
192
|
+
(step > 0) ? len : len - 1);
|
|
193
|
+
}
|
|
194
|
+
if (raw_stop == SLICE_NONE) {
|
|
195
|
+
stop = (step > 0) ? len : std::ptrdiff_t{-1};
|
|
196
|
+
} else {
|
|
197
|
+
stop = raw_stop;
|
|
198
|
+
if (stop < 0) stop += len;
|
|
199
|
+
stop = std::clamp(stop, std::ptrdiff_t{-1}, len);
|
|
200
|
+
}
|
|
201
|
+
return {start, stop, step};
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
} // namespace detail
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* str_stepped_slice - Python-style stepped string slicing: s[start:stop:step].
|
|
208
|
+
* Returns a new owned string (non-contiguous).
|
|
209
|
+
*/
|
|
210
|
+
inline std::string str_stepped_slice(std::string_view s, int32_t start, int32_t stop, int32_t step) {
|
|
211
|
+
auto len = static_cast<std::ptrdiff_t>(s.size());
|
|
212
|
+
auto [i, j, st] = detail::resolve_stepped_bounds(start, stop, step, len);
|
|
213
|
+
std::string result;
|
|
214
|
+
if (st > 0) {
|
|
215
|
+
for (auto k = i; k < j; k += st)
|
|
216
|
+
result += s[static_cast<std::size_t>(k)];
|
|
217
|
+
} else {
|
|
218
|
+
for (auto k = i; k > j; k += st)
|
|
219
|
+
result += s[static_cast<std::size_t>(k)];
|
|
220
|
+
}
|
|
221
|
+
return result;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* list_stepped_slice - Python-style stepped container slicing: c[start:stop:step].
|
|
226
|
+
* Returns a new owned vector (non-contiguous).
|
|
227
|
+
*/
|
|
228
|
+
template <typename Container>
|
|
229
|
+
auto list_stepped_slice(const Container& c, int32_t start, int32_t stop, int32_t step) {
|
|
230
|
+
using T = std::remove_const_t<std::remove_reference_t<decltype(c[0])>>;
|
|
231
|
+
auto len = static_cast<std::ptrdiff_t>(c.size());
|
|
232
|
+
auto [i, j, st] = detail::resolve_stepped_bounds(start, stop, step, len);
|
|
233
|
+
std::vector<T> result;
|
|
234
|
+
if (st > 0) {
|
|
235
|
+
for (auto k = i; k < j; k += st)
|
|
236
|
+
result.push_back(c[static_cast<std::size_t>(k)]);
|
|
237
|
+
} else {
|
|
238
|
+
for (auto k = i; k > j; k += st)
|
|
239
|
+
result.push_back(c[static_cast<std::size_t>(k)]);
|
|
240
|
+
}
|
|
241
|
+
return result;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/// Slice overloads: unpack start/stop/step from the slice object.
|
|
245
|
+
inline std::string str_stepped_slice(std::string_view s, Slice sl) {
|
|
246
|
+
return str_stepped_slice(s, sl.start.value_or(SLICE_NONE),
|
|
247
|
+
sl.stop.value_or(SLICE_NONE),
|
|
248
|
+
sl.step.value_or(1));
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
template <typename Container>
|
|
252
|
+
auto list_stepped_slice(const Container& c, Slice sl) {
|
|
253
|
+
return list_stepped_slice(c, sl.start.value_or(SLICE_NONE),
|
|
254
|
+
sl.stop.value_or(SLICE_NONE),
|
|
255
|
+
sl.step.value_or(1));
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* list_set_stepped_slice - Python-style stepped slice assignment: a[start:stop:step] = values.
|
|
260
|
+
* Replaces elements at stepped positions. Unlike basic slice assignment, the RHS
|
|
261
|
+
* must have exactly the same number of elements as the slice selects (Python semantics).
|
|
262
|
+
* Exception: step==1 is equivalent to basic slice assignment (allows resize).
|
|
263
|
+
*/
|
|
264
|
+
template<typename T, typename Range>
|
|
265
|
+
requires std::ranges::input_range<const Range>
|
|
266
|
+
void list_set_stepped_slice(std::vector<T>& vec, int32_t start, int32_t stop, int32_t step, const Range& values) {
|
|
267
|
+
// step==1 is equivalent to basic slice assignment (allows resize)
|
|
268
|
+
if (step == 1) {
|
|
269
|
+
auto resolved_start = (start == SLICE_NONE) ? 0 : start;
|
|
270
|
+
auto resolved_stop = (stop == SLICE_NONE) ? SLICE_END : stop;
|
|
271
|
+
list_set_slice(vec, resolved_start, resolved_stop, values);
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
auto len = static_cast<std::ptrdiff_t>(vec.size());
|
|
275
|
+
auto [i, j, st] = detail::resolve_stepped_bounds(start, stop, step, len);
|
|
276
|
+
// Collect target indices
|
|
277
|
+
std::vector<std::ptrdiff_t> indices;
|
|
278
|
+
if (st > 0) {
|
|
279
|
+
for (auto k = i; k < j; k += st) indices.push_back(k);
|
|
280
|
+
} else {
|
|
281
|
+
for (auto k = i; k > j; k += st) indices.push_back(k);
|
|
282
|
+
}
|
|
283
|
+
// Collect values first to validate length before mutating vec
|
|
284
|
+
std::vector<T> vals(std::ranges::begin(values), std::ranges::end(values));
|
|
285
|
+
if (vals.size() != indices.size()) {
|
|
286
|
+
raise_value_error("attempt to assign sequence of size {} to extended slice of size {}",
|
|
287
|
+
vals.size(), indices.size());
|
|
288
|
+
}
|
|
289
|
+
// Self-aliasing guard: vals is already a copy, so safe to assign
|
|
290
|
+
for (std::size_t idx = 0; idx < indices.size(); ++idx) {
|
|
291
|
+
vec[static_cast<std::size_t>(indices[idx])] = std::move(vals[idx]);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/// Slice overload: unpacks start/stop/step from the slice object.
|
|
296
|
+
template<typename T, typename Range>
|
|
297
|
+
requires std::ranges::input_range<const Range>
|
|
298
|
+
void list_set_stepped_slice(std::vector<T>& vec, Slice sl, const Range& values) {
|
|
299
|
+
list_set_stepped_slice(vec, sl.start.value_or(SLICE_NONE),
|
|
300
|
+
sl.stop.value_or(SLICE_NONE),
|
|
301
|
+
sl.step.value_or(1), values);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// =============================================
|
|
305
|
+
// std::vector list methods
|
|
306
|
+
// =============================================
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* list_insert - Python list.insert() for std::vector.
|
|
310
|
+
*
|
|
311
|
+
* Inserts value at index. Supports negative indexing and clamps to valid range
|
|
312
|
+
* (Python semantics: -1 inserts before last element, out-of-range clamps).
|
|
313
|
+
* Uses perfect forwarding to support both copy and move.
|
|
314
|
+
*/
|
|
315
|
+
template<typename T, typename V>
|
|
316
|
+
void list_insert(std::vector<T>& v, int32_t index, V&& value) {
|
|
317
|
+
std::ptrdiff_t i = index;
|
|
318
|
+
auto sz = static_cast<std::ptrdiff_t>(v.size());
|
|
319
|
+
if (i < 0) {
|
|
320
|
+
i += sz;
|
|
321
|
+
if (i < 0) i = 0; // Clamp to start
|
|
322
|
+
} else if (i > sz) {
|
|
323
|
+
i = sz; // Clamp to end
|
|
324
|
+
}
|
|
325
|
+
v.insert(v.begin() + i, std::forward<V>(value));
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* list_remove - Python list.remove() for std::vector.
|
|
330
|
+
*
|
|
331
|
+
* Removes first occurrence of value. Panics if not found.
|
|
332
|
+
*/
|
|
333
|
+
template<typename T>
|
|
334
|
+
void list_remove(std::vector<T>& v, const T& value) {
|
|
335
|
+
auto it = std::find(v.begin(), v.end(), value);
|
|
336
|
+
if (it == v.end()) {
|
|
337
|
+
raise_value_error("list.remove(x): x not in list");
|
|
338
|
+
}
|
|
339
|
+
v.erase(it);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* list_extend - Python list.extend() for std::vector.
|
|
344
|
+
*
|
|
345
|
+
* Extends vector with elements from another container.
|
|
346
|
+
* Overloads handle both iterator-based containers and initializer_list.
|
|
347
|
+
*/
|
|
348
|
+
template<typename T, typename Container>
|
|
349
|
+
requires std::ranges::input_range<std::remove_cvref_t<Container>>
|
|
350
|
+
void list_extend(std::vector<T>& v, Container&& other) {
|
|
351
|
+
v.insert(v.end(), other.begin(), other.end());
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
template<typename T>
|
|
355
|
+
void list_extend(std::vector<T>& v, std::initializer_list<T> other) {
|
|
356
|
+
v.insert(v.end(), other);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* list_concat - Python list.__add__ (a + b) for std::vector.
|
|
361
|
+
*
|
|
362
|
+
* Returns a new vector containing elements from both vectors.
|
|
363
|
+
*/
|
|
364
|
+
template<typename T>
|
|
365
|
+
std::vector<T> list_concat(const std::vector<T>& a, const std::vector<T>& b) {
|
|
366
|
+
std::vector<T> result;
|
|
367
|
+
result.reserve(a.size() + b.size());
|
|
368
|
+
result.insert(result.end(), a.begin(), a.end());
|
|
369
|
+
result.insert(result.end(), b.begin(), b.end());
|
|
370
|
+
return result;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* list_pop_at - Python list.pop(index) for std::vector.
|
|
375
|
+
*
|
|
376
|
+
* Removes and returns element at index. Supports negative indexing.
|
|
377
|
+
* Throws IndexError if index is out of bounds.
|
|
378
|
+
*/
|
|
379
|
+
template<typename T>
|
|
380
|
+
T list_pop_at(std::vector<T>& v, int32_t index) {
|
|
381
|
+
auto i = normalize_index(v, index, "pop index out of range");
|
|
382
|
+
T result = std::move(v[i]);
|
|
383
|
+
v.erase(v.begin() + static_cast<std::ptrdiff_t>(i));
|
|
384
|
+
return result;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* list_index - Python list.index(value) for std::vector.
|
|
389
|
+
*
|
|
390
|
+
* Returns index of first occurrence of value. Panics if not found.
|
|
391
|
+
*/
|
|
392
|
+
template<typename T>
|
|
393
|
+
int32_t list_index(const std::vector<T>& v, const T& value) {
|
|
394
|
+
auto it = std::find(v.begin(), v.end(), value);
|
|
395
|
+
if (it == v.end()) {
|
|
396
|
+
raise_value_error("list.index(x): x not in list");
|
|
397
|
+
}
|
|
398
|
+
return static_cast<int32_t>(it - v.begin());
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* list_count - Python list.count(value) for std::vector.
|
|
403
|
+
*
|
|
404
|
+
* Returns number of occurrences of value.
|
|
405
|
+
*/
|
|
406
|
+
template<typename T>
|
|
407
|
+
int32_t list_count(const std::vector<T>& v, const T& value) {
|
|
408
|
+
return static_cast<int32_t>(std::count(v.begin(), v.end(), value));
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* list_reverse - Python list.reverse() for std::vector.
|
|
413
|
+
*
|
|
414
|
+
* Reverses the list in place.
|
|
415
|
+
*/
|
|
416
|
+
template<typename T>
|
|
417
|
+
void list_reverse(std::vector<T>& v) {
|
|
418
|
+
std::reverse(v.begin(), v.end());
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
/**
|
|
422
|
+
* list_copy - Python list.copy() for std::vector.
|
|
423
|
+
*
|
|
424
|
+
* Returns a shallow copy of the list.
|
|
425
|
+
*/
|
|
426
|
+
template<typename T>
|
|
427
|
+
std::vector<T> list_copy(const std::vector<T>& v) {
|
|
428
|
+
return v;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
// =============================================
|
|
432
|
+
// Span helpers (as_span, as_mut_span)
|
|
433
|
+
// =============================================
|
|
434
|
+
|
|
435
|
+
template <typename T, std::size_t N>
|
|
436
|
+
inline std::span<const T> as_span(const std::array<T, N>& arr) {
|
|
437
|
+
return std::span<const T>(arr);
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
template <typename T>
|
|
441
|
+
inline std::span<const T> as_span(const std::vector<T>& vec) {
|
|
442
|
+
return std::span<const T>(vec.data(), vec.size());
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
template <typename T>
|
|
446
|
+
inline std::span<const T> as_span(std::span<const T> span) {
|
|
447
|
+
return span;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
template <typename T>
|
|
451
|
+
inline std::span<const T> as_span(std::span<T> span) {
|
|
452
|
+
return span;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
// User types with __span__(): delegate to their method.
|
|
456
|
+
// The specific overloads above (vector, array, span) are more specialized
|
|
457
|
+
// and always preferred over this template.
|
|
458
|
+
template <typename T>
|
|
459
|
+
requires requires(const T& t) { t.__span__(); }
|
|
460
|
+
inline auto as_span(const T& t) {
|
|
461
|
+
return t.__span__();
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
// --- Mutable span helpers ---
|
|
465
|
+
|
|
466
|
+
template <typename T, std::size_t N>
|
|
467
|
+
inline std::span<T> as_mut_span(std::array<T, N>& arr) {
|
|
468
|
+
return std::span<T>(arr);
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
// Rvalue overload: safe when span is consumed within the full-expression (ARG context)
|
|
472
|
+
template <typename T, std::size_t N>
|
|
473
|
+
inline std::span<T> as_mut_span(std::array<T, N>&& arr) {
|
|
474
|
+
return std::span<T>(arr.data(), arr.size());
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
template <typename T>
|
|
478
|
+
inline std::span<T> as_mut_span(std::vector<T>& vec) {
|
|
479
|
+
return std::span<T>(vec.data(), vec.size());
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
template <typename T>
|
|
483
|
+
inline std::span<T> as_mut_span(std::span<T> span) {
|
|
484
|
+
return span;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
} // namespace tpy
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TurboPython Runtime - CopyIter
|
|
3
|
+
*
|
|
4
|
+
* Iterator adapter that copies each element from a borrowing iterator.
|
|
5
|
+
* Used by copy_iter() to acknowledge element-by-element copies when
|
|
6
|
+
* extending containers. Each element is copied directly into the
|
|
7
|
+
* destination -- no intermediate container copy.
|
|
8
|
+
*
|
|
9
|
+
* Implements the TurboPython Iterator protocol (__next__/__iter__).
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
#pragma once
|
|
13
|
+
|
|
14
|
+
#include "core.hpp"
|
|
15
|
+
#include "dunder.hpp"
|
|
16
|
+
|
|
17
|
+
#include <expected>
|
|
18
|
+
|
|
19
|
+
namespace tpy {
|
|
20
|
+
|
|
21
|
+
template<typename T, typename Inner>
|
|
22
|
+
struct CopyIter {
|
|
23
|
+
Inner inner;
|
|
24
|
+
|
|
25
|
+
// Iterator protocol: copy each element from the inner iterator.
|
|
26
|
+
// unwrap_ref_move copies from val_or_ref (borrowed) and moves from
|
|
27
|
+
// owned values; the tuple overload handles nested val_or_ref elements.
|
|
28
|
+
std::expected<T, StopIteration> __next__() {
|
|
29
|
+
auto r = inner.__next__();
|
|
30
|
+
if (!r.has_value()) return tpy::make_unexpected(StopIteration{});
|
|
31
|
+
return T(unwrap_ref_move(*r));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
CopyIter& __iter__() { return *this; }
|
|
35
|
+
|
|
36
|
+
// Minimal input iterator for codegen begin/end loops (for-each).
|
|
37
|
+
// Not a formal std::input_iterator (no default ctor, no operator==),
|
|
38
|
+
// so CopyIter does NOT satisfy std::ranges::input_range. When passed
|
|
39
|
+
// to tpy::construct(), it routes through the __next__() (collect) path.
|
|
40
|
+
struct Sentinel {};
|
|
41
|
+
struct Iterator {
|
|
42
|
+
CopyIter* parent;
|
|
43
|
+
std::optional<T> current;
|
|
44
|
+
|
|
45
|
+
Iterator& operator++() {
|
|
46
|
+
auto r = parent->__next__();
|
|
47
|
+
current = r.has_value() ? std::optional<T>(std::move(*r)) : std::nullopt;
|
|
48
|
+
return *this;
|
|
49
|
+
}
|
|
50
|
+
T& operator*() { return *current; }
|
|
51
|
+
bool operator!=(Sentinel) const { return current.has_value(); }
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
Iterator begin() {
|
|
55
|
+
Iterator it{this, std::nullopt};
|
|
56
|
+
++it; // prime with first element
|
|
57
|
+
return it;
|
|
58
|
+
}
|
|
59
|
+
Sentinel end() { return {}; }
|
|
60
|
+
|
|
61
|
+
friend std::ostream& operator<<(std::ostream& os, const CopyIter&) {
|
|
62
|
+
return os << "<copy_iter>";
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// Factory: create CopyIter from a container by calling __iter__ and wrapping.
|
|
67
|
+
// Excluded for iterator types (have __next__) -- use the rvalue overload via std::move.
|
|
68
|
+
template<typename T, typename Container>
|
|
69
|
+
requires (!requires(Container& c) { c.__next__(); })
|
|
70
|
+
auto copy_iter(Container& c) {
|
|
71
|
+
auto it = tpy::__iter__(c);
|
|
72
|
+
return CopyIter<T, decltype(it)>{std::move(it)};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Rvalue overload: wrap an iterator directly (e.g. copy_iter(map(f, xs))).
|
|
76
|
+
template<typename T, typename Iter>
|
|
77
|
+
requires (!std::is_lvalue_reference_v<Iter&&>)
|
|
78
|
+
auto copy_iter(Iter&& iter) {
|
|
79
|
+
return CopyIter<T, std::remove_cvref_t<Iter>>{std::move(iter)};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
} // namespace tpy
|