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,749 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TurboPython Runtime - Iterator Builtins
|
|
3
|
+
*
|
|
4
|
+
* enumerate(), zip(), reversed(), map(), and filter() implementations.
|
|
5
|
+
* Depends on: next_iter.hpp, dunder.hpp (for __iter__, __len__, __getitem__)
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#include "next_iter.hpp"
|
|
11
|
+
#include "dunder.hpp"
|
|
12
|
+
#include "type_traits.hpp"
|
|
13
|
+
|
|
14
|
+
#include <cstdint>
|
|
15
|
+
#include <expected>
|
|
16
|
+
#include <optional>
|
|
17
|
+
#include <tuple>
|
|
18
|
+
|
|
19
|
+
namespace tpy {
|
|
20
|
+
|
|
21
|
+
// -- enumerate --
|
|
22
|
+
|
|
23
|
+
template<typename T, typename Iter>
|
|
24
|
+
class enumerate_iter : public next_iter_mixin<enumerate_iter<T, Iter>, std::tuple<int32_t, T>> {
|
|
25
|
+
Iter iter_;
|
|
26
|
+
int32_t index_; // TPy uses Int32; Python enumerate uses arbitrary-precision
|
|
27
|
+
public:
|
|
28
|
+
enumerate_iter(Iter&& iter, int32_t start = 0) : iter_(std::move(iter)), index_(start) {}
|
|
29
|
+
|
|
30
|
+
std::expected<std::tuple<int32_t, T>, StopIteration> __next__() {
|
|
31
|
+
auto r = iter_.__next__();
|
|
32
|
+
if (!r.has_value()) return tpy::make_unexpected(StopIteration{});
|
|
33
|
+
return std::tuple<int32_t, T>{index_++, unwrap_ref(*r)};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
enumerate_iter& __iter__() { return *this; }
|
|
37
|
+
|
|
38
|
+
friend std::ostream& operator<<(std::ostream& os, const enumerate_iter&) {
|
|
39
|
+
return os << "<enumerate>";
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
// Owning variant: moves the container in so rvalue arguments don't dangle.
|
|
44
|
+
template<typename T, typename Container>
|
|
45
|
+
class owning_enumerate_iter
|
|
46
|
+
: public next_iter_mixin<owning_enumerate_iter<T, Container>, std::tuple<int32_t, T>> {
|
|
47
|
+
using Iter = decltype(tpy::__iter__(std::declval<Container&>()));
|
|
48
|
+
Container owned_;
|
|
49
|
+
Iter iter_;
|
|
50
|
+
int32_t index_;
|
|
51
|
+
public:
|
|
52
|
+
owning_enumerate_iter(Container&& c, int32_t start = 0)
|
|
53
|
+
: owned_(std::move(c)), iter_(tpy::__iter__(owned_)), index_(start) {}
|
|
54
|
+
|
|
55
|
+
// iter_ points into owned_; moving would invalidate it (e.g. for std::array).
|
|
56
|
+
// Rely on guaranteed copy elision from the factory functions.
|
|
57
|
+
owning_enumerate_iter(owning_enumerate_iter&&) = delete;
|
|
58
|
+
owning_enumerate_iter& operator=(owning_enumerate_iter&&) = delete;
|
|
59
|
+
|
|
60
|
+
std::expected<std::tuple<int32_t, T>, StopIteration> __next__() {
|
|
61
|
+
auto r = iter_.__next__();
|
|
62
|
+
if (!r.has_value()) return tpy::make_unexpected(StopIteration{});
|
|
63
|
+
return std::tuple<int32_t, T>{index_++, unwrap_ref(*r)};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
owning_enumerate_iter& __iter__() { return *this; }
|
|
67
|
+
|
|
68
|
+
friend std::ostream& operator<<(std::ostream& os, const owning_enumerate_iter&) {
|
|
69
|
+
return os << "<enumerate>";
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
// Direct-iteration variant: uses C++ begin/end to get references to container
|
|
74
|
+
// elements instead of going through __iter__/__next__() which copies.
|
|
75
|
+
template<typename T, typename Container>
|
|
76
|
+
class enumerate_direct_iter
|
|
77
|
+
: public next_iter_mixin<enumerate_direct_iter<T, Container>,
|
|
78
|
+
std::tuple<int32_t, val_or_ref_t<T>>> {
|
|
79
|
+
using CppIter = decltype(std::declval<Container&>().begin());
|
|
80
|
+
Container& container_;
|
|
81
|
+
CppIter it_;
|
|
82
|
+
CppIter end_;
|
|
83
|
+
int32_t index_;
|
|
84
|
+
public:
|
|
85
|
+
enumerate_direct_iter(Container& c, int32_t start = 0)
|
|
86
|
+
: container_(c), it_(c.begin()), end_(c.end()), index_(start) {}
|
|
87
|
+
|
|
88
|
+
std::expected<std::tuple<int32_t, val_or_ref_t<T>>, StopIteration> __next__() {
|
|
89
|
+
if (it_ == end_) return tpy::make_unexpected(StopIteration{});
|
|
90
|
+
return std::tuple<int32_t, val_or_ref_t<T>>{index_++, *it_++};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
enumerate_direct_iter& __iter__() { return *this; }
|
|
94
|
+
|
|
95
|
+
friend std::ostream& operator<<(std::ostream& os, const enumerate_direct_iter&) {
|
|
96
|
+
return os << "<enumerate>";
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
// Owning direct-iteration variant for rvalue containers.
|
|
101
|
+
template<typename T, typename Container>
|
|
102
|
+
class owning_enumerate_direct_iter
|
|
103
|
+
: public next_iter_mixin<owning_enumerate_direct_iter<T, Container>,
|
|
104
|
+
std::tuple<int32_t, val_or_ref_t<T>>> {
|
|
105
|
+
using CppIter = decltype(std::declval<Container&>().begin());
|
|
106
|
+
Container owned_;
|
|
107
|
+
CppIter it_;
|
|
108
|
+
CppIter end_;
|
|
109
|
+
int32_t index_;
|
|
110
|
+
public:
|
|
111
|
+
owning_enumerate_direct_iter(Container&& c, int32_t start = 0)
|
|
112
|
+
: owned_(std::move(c)), it_(owned_.begin()), end_(owned_.end()), index_(start) {}
|
|
113
|
+
|
|
114
|
+
owning_enumerate_direct_iter(owning_enumerate_direct_iter&&) = delete;
|
|
115
|
+
owning_enumerate_direct_iter& operator=(owning_enumerate_direct_iter&&) = delete;
|
|
116
|
+
|
|
117
|
+
std::expected<std::tuple<int32_t, val_or_ref_t<T>>, StopIteration> __next__() {
|
|
118
|
+
if (it_ == end_) return tpy::make_unexpected(StopIteration{});
|
|
119
|
+
return std::tuple<int32_t, val_or_ref_t<T>>{index_++, *it_++};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
owning_enumerate_direct_iter& __iter__() { return *this; }
|
|
123
|
+
|
|
124
|
+
friend std::ostream& operator<<(std::ostream& os, const owning_enumerate_direct_iter&) {
|
|
125
|
+
return os << "<enumerate>";
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
namespace detail {
|
|
130
|
+
// Requires homogeneous begin/end (same iterator type) so enumerate_direct_iter
|
|
131
|
+
// can store both as CppIter. Excludes next_iter_mixin-derived types whose
|
|
132
|
+
// begin() returns NextIterator<...> but end() returns NextSentinel.
|
|
133
|
+
template<typename T>
|
|
134
|
+
concept has_begin_end = requires(T& t) { t.begin(); t.end(); }
|
|
135
|
+
&& std::same_as<decltype(std::declval<T&>().begin()), decltype(std::declval<T&>().end())>;
|
|
136
|
+
|
|
137
|
+
// Extract Nth parameter type from a callable (function pointer, lambda, std::function).
|
|
138
|
+
// Used by map_multi_iter to forward Own[T] args as rvalue refs.
|
|
139
|
+
// Generic lambdas (auto params) are not supported -- tpyc always emits
|
|
140
|
+
// monomorphic lambdas with concrete parameter types.
|
|
141
|
+
template<typename F> struct fn_params;
|
|
142
|
+
template<typename R, typename... A> struct fn_params<R(*)(A...)> { using types = std::tuple<A...>; };
|
|
143
|
+
template<typename R, typename... A> struct fn_params<R(&)(A...)> { using types = std::tuple<A...>; };
|
|
144
|
+
template<typename C, typename R, typename... A> struct fn_params<R(C::*)(A...) const> { using types = std::tuple<A...>; };
|
|
145
|
+
template<typename C, typename R, typename... A> struct fn_params<R(C::*)(A...)> { using types = std::tuple<A...>; };
|
|
146
|
+
|
|
147
|
+
template<typename F>
|
|
148
|
+
concept has_call_op = requires { &std::remove_cvref_t<F>::operator(); };
|
|
149
|
+
|
|
150
|
+
template<has_call_op F> struct fn_params<F> : fn_params<decltype(&std::remove_cvref_t<F>::operator())> {};
|
|
151
|
+
|
|
152
|
+
template<typename F, size_t N>
|
|
153
|
+
using fn_param_t = std::tuple_element_t<N, typename fn_params<std::remove_cvref_t<F>>::types>;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// lvalue: direct iteration for containers (preserves references),
|
|
157
|
+
// __iter__/__next__() fallback for TPy iterators
|
|
158
|
+
template<typename T, typename Iterable>
|
|
159
|
+
auto builtin_enumerate(Iterable& iterable) {
|
|
160
|
+
if constexpr (detail::has_begin_end<Iterable>) {
|
|
161
|
+
return enumerate_direct_iter<T, Iterable>(iterable);
|
|
162
|
+
} else {
|
|
163
|
+
auto iter = tpy::__iter__(iterable);
|
|
164
|
+
return enumerate_iter<T, decltype(iter)>(std::move(iter));
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// rvalue: own the container to prevent dangling iterators
|
|
169
|
+
template<typename T, typename Iterable>
|
|
170
|
+
requires (!std::is_lvalue_reference_v<Iterable&&>)
|
|
171
|
+
auto builtin_enumerate(Iterable&& iterable) {
|
|
172
|
+
if constexpr (detail::has_begin_end<Iterable>) {
|
|
173
|
+
return owning_enumerate_direct_iter<T, std::remove_cvref_t<Iterable>>(std::move(iterable));
|
|
174
|
+
} else {
|
|
175
|
+
return owning_enumerate_iter<T, std::remove_cvref_t<Iterable>>(std::move(iterable));
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// lvalue with start
|
|
180
|
+
template<typename T, typename Iterable>
|
|
181
|
+
auto builtin_enumerate_start(Iterable& iterable, int32_t start) {
|
|
182
|
+
if constexpr (detail::has_begin_end<Iterable>) {
|
|
183
|
+
return enumerate_direct_iter<T, Iterable>(iterable, start);
|
|
184
|
+
} else {
|
|
185
|
+
auto iter = tpy::__iter__(iterable);
|
|
186
|
+
return enumerate_iter<T, decltype(iter)>(std::move(iter), start);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// rvalue with start
|
|
191
|
+
template<typename T, typename Iterable>
|
|
192
|
+
requires (!std::is_lvalue_reference_v<Iterable&&>)
|
|
193
|
+
auto builtin_enumerate_start(Iterable&& iterable, int32_t start) {
|
|
194
|
+
if constexpr (detail::has_begin_end<Iterable>) {
|
|
195
|
+
return owning_enumerate_direct_iter<T, std::remove_cvref_t<Iterable>>(std::move(iterable), start);
|
|
196
|
+
} else {
|
|
197
|
+
return owning_enumerate_iter<T, std::remove_cvref_t<Iterable>>(std::move(iterable), start);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// -- zip (variadic) --
|
|
202
|
+
|
|
203
|
+
// Tag to carry element types through partial specialization (two-pack workaround).
|
|
204
|
+
template<typename... Ts> struct zip_types {};
|
|
205
|
+
|
|
206
|
+
namespace detail {
|
|
207
|
+
|
|
208
|
+
// Advance all iterators into optionals; returns false if any is exhausted.
|
|
209
|
+
// Uses unwrap() to unwrap val_or_ref from native_iterator __next__().
|
|
210
|
+
template<typename Tuple, typename... Opts, std::size_t... Is>
|
|
211
|
+
bool zip_advance(Tuple& iters, std::tuple<Opts...>& opts, std::index_sequence<Is...>) {
|
|
212
|
+
bool ok = true;
|
|
213
|
+
// && short-circuits: once ok is false, remaining lambdas are not called.
|
|
214
|
+
// Matches Python zip() -- stop at shortest without over-advancing.
|
|
215
|
+
((ok = ok && [&]{
|
|
216
|
+
auto r = std::get<Is>(iters).__next__();
|
|
217
|
+
if (!r.has_value()) return false;
|
|
218
|
+
std::get<Is>(opts).emplace(tpy::unwrap_ref(*r));
|
|
219
|
+
return true;
|
|
220
|
+
}()), ...);
|
|
221
|
+
return ok;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// Build a tuple by moving out of the optionals.
|
|
225
|
+
template<typename... Ts, std::size_t... Is>
|
|
226
|
+
std::tuple<Ts...> zip_collect(std::tuple<std::optional<Ts>...>& opts, std::index_sequence<Is...>) {
|
|
227
|
+
return std::tuple<Ts...>{std::move(*std::get<Is>(opts))...};
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
} // namespace detail
|
|
231
|
+
|
|
232
|
+
// Primary template (never instantiated directly).
|
|
233
|
+
template<typename TypeTag, typename... Iters>
|
|
234
|
+
class zip_iter;
|
|
235
|
+
|
|
236
|
+
// Partial specialization unpacks the element types from the tag.
|
|
237
|
+
template<typename... Ts, typename... Iters>
|
|
238
|
+
class zip_iter<zip_types<Ts...>, Iters...>
|
|
239
|
+
: public next_iter_mixin<zip_iter<zip_types<Ts...>, Iters...>, std::tuple<Ts...>> {
|
|
240
|
+
std::tuple<Iters...> iters_;
|
|
241
|
+
public:
|
|
242
|
+
explicit zip_iter(Iters&&... iters) : iters_(std::move(iters)...) {}
|
|
243
|
+
|
|
244
|
+
std::expected<std::tuple<Ts...>, StopIteration> __next__() {
|
|
245
|
+
std::tuple<std::optional<Ts>...> opts;
|
|
246
|
+
if (!detail::zip_advance(iters_, opts, std::index_sequence_for<Iters...>{}))
|
|
247
|
+
return tpy::make_unexpected(StopIteration{});
|
|
248
|
+
return detail::zip_collect<Ts...>(opts, std::index_sequence_for<Ts...>{});
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
zip_iter& __iter__() { return *this; }
|
|
252
|
+
|
|
253
|
+
friend std::ostream& operator<<(std::ostream& os, const zip_iter&) {
|
|
254
|
+
return os << "<zip>";
|
|
255
|
+
}
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
template<typename TypeTag, typename... Containers>
|
|
259
|
+
class owning_zip_iter;
|
|
260
|
+
|
|
261
|
+
template<typename... Ts, typename... Containers>
|
|
262
|
+
class owning_zip_iter<zip_types<Ts...>, Containers...>
|
|
263
|
+
: public next_iter_mixin<owning_zip_iter<zip_types<Ts...>, Containers...>, std::tuple<Ts...>> {
|
|
264
|
+
std::tuple<Containers...> owned_;
|
|
265
|
+
// Store iterators by value (not reference). __iter__() on __next__-based
|
|
266
|
+
// types (map_iter, etc.) returns Self& -- storing that reference would
|
|
267
|
+
// dangle after make_iters returns. remove_reference_t copies the iterator.
|
|
268
|
+
std::tuple<std::remove_reference_t<decltype(tpy::__iter__(std::declval<Containers&>()))>...> iters_;
|
|
269
|
+
|
|
270
|
+
template<std::size_t... Is>
|
|
271
|
+
auto make_iters(std::index_sequence<Is...>) {
|
|
272
|
+
return std::tuple{tpy::__iter__(std::get<Is>(owned_))...};
|
|
273
|
+
}
|
|
274
|
+
public:
|
|
275
|
+
template<typename... Us>
|
|
276
|
+
explicit owning_zip_iter(Us&&... cs)
|
|
277
|
+
: owned_(std::forward<Us>(cs)...),
|
|
278
|
+
iters_(make_iters(std::index_sequence_for<Containers...>{})) {}
|
|
279
|
+
|
|
280
|
+
owning_zip_iter(const owning_zip_iter&) = delete;
|
|
281
|
+
owning_zip_iter& operator=(const owning_zip_iter&) = delete;
|
|
282
|
+
owning_zip_iter(owning_zip_iter&&) = delete;
|
|
283
|
+
owning_zip_iter& operator=(owning_zip_iter&&) = delete;
|
|
284
|
+
|
|
285
|
+
std::expected<std::tuple<Ts...>, StopIteration> __next__() {
|
|
286
|
+
std::tuple<std::optional<Ts>...> opts;
|
|
287
|
+
if (!detail::zip_advance(iters_, opts, std::index_sequence_for<Containers...>{}))
|
|
288
|
+
return tpy::make_unexpected(StopIteration{});
|
|
289
|
+
return detail::zip_collect<Ts...>(opts, std::index_sequence_for<Ts...>{});
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
owning_zip_iter& __iter__() { return *this; }
|
|
293
|
+
|
|
294
|
+
friend std::ostream& operator<<(std::ostream& os, const owning_zip_iter&) {
|
|
295
|
+
return os << "<zip>";
|
|
296
|
+
}
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
// Direct-iteration zip: uses C++ begin/end for reference-preserving iteration.
|
|
300
|
+
template<typename TypeTag, typename... Containers>
|
|
301
|
+
class zip_direct_iter;
|
|
302
|
+
|
|
303
|
+
template<typename... Ts, typename... Containers>
|
|
304
|
+
class zip_direct_iter<zip_types<Ts...>, Containers...>
|
|
305
|
+
: public next_iter_mixin<zip_direct_iter<zip_types<Ts...>, Containers...>,
|
|
306
|
+
std::tuple<val_or_ref_t<Ts>...>> {
|
|
307
|
+
std::tuple<decltype(std::declval<Containers&>().begin())...> its_;
|
|
308
|
+
std::tuple<decltype(std::declval<Containers&>().end())...> ends_;
|
|
309
|
+
|
|
310
|
+
template<std::size_t... Is>
|
|
311
|
+
bool any_at_end(std::index_sequence<Is...>) const {
|
|
312
|
+
return ((std::get<Is>(its_) == std::get<Is>(ends_)) || ...);
|
|
313
|
+
}
|
|
314
|
+
template<std::size_t... Is>
|
|
315
|
+
std::tuple<val_or_ref_t<Ts>...> deref_and_advance(std::index_sequence<Is...>) {
|
|
316
|
+
return std::tuple<val_or_ref_t<Ts>...>{*std::get<Is>(its_)++...};
|
|
317
|
+
}
|
|
318
|
+
public:
|
|
319
|
+
explicit zip_direct_iter(Containers&... cs)
|
|
320
|
+
: its_(cs.begin()...), ends_(cs.end()...) {}
|
|
321
|
+
|
|
322
|
+
std::expected<std::tuple<val_or_ref_t<Ts>...>, StopIteration> __next__() {
|
|
323
|
+
if (any_at_end(std::index_sequence_for<Containers...>{}))
|
|
324
|
+
return tpy::make_unexpected(StopIteration{});
|
|
325
|
+
return deref_and_advance(std::index_sequence_for<Containers...>{});
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
zip_direct_iter& __iter__() { return *this; }
|
|
329
|
+
|
|
330
|
+
friend std::ostream& operator<<(std::ostream& os, const zip_direct_iter&) {
|
|
331
|
+
return os << "<zip>";
|
|
332
|
+
}
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
// lvalue factory: direct iteration for containers, __iter__ fallback otherwise
|
|
336
|
+
template<typename... Ts, typename... Cs>
|
|
337
|
+
auto builtin_zip(Cs&... cs) {
|
|
338
|
+
if constexpr ((detail::has_begin_end<Cs> && ...)) {
|
|
339
|
+
return zip_direct_iter<zip_types<Ts...>, Cs...>(cs...);
|
|
340
|
+
} else {
|
|
341
|
+
return zip_iter<zip_types<Ts...>, decltype(tpy::__iter__(cs))...>(tpy::__iter__(cs)...);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// Mixed factory (at least one rvalue): per-arg own (rvalue) or borrow (lvalue).
|
|
346
|
+
// std::tuple natively supports reference members, so lvalue args store as C&
|
|
347
|
+
// (zero-copy borrow) while rvalue args store as C (moved in).
|
|
348
|
+
template<typename... Ts, typename... Cs>
|
|
349
|
+
requires ((!std::is_lvalue_reference_v<Cs&&>) || ...)
|
|
350
|
+
auto builtin_zip(Cs&&... cs) {
|
|
351
|
+
return owning_zip_iter<zip_types<Ts...>,
|
|
352
|
+
std::conditional_t<std::is_lvalue_reference_v<Cs&&>,
|
|
353
|
+
std::remove_reference_t<Cs>&,
|
|
354
|
+
std::remove_cvref_t<Cs>>...>(
|
|
355
|
+
std::forward<Cs>(cs)...);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+
// -- reversed --
|
|
360
|
+
|
|
361
|
+
template<typename T, typename Seq>
|
|
362
|
+
class reversed_iter : public next_iter_mixin<reversed_iter<T, Seq>, T> {
|
|
363
|
+
const Seq& seq_;
|
|
364
|
+
int32_t index_;
|
|
365
|
+
public:
|
|
366
|
+
reversed_iter(const Seq& seq) : seq_(seq), index_(tpy::__len__(seq) - 1) {}
|
|
367
|
+
|
|
368
|
+
std::expected<T, StopIteration> __next__() {
|
|
369
|
+
if (index_ < 0) return tpy::make_unexpected(StopIteration{});
|
|
370
|
+
return tpy::__getitem__(seq_, index_--);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
reversed_iter& __iter__() { return *this; }
|
|
374
|
+
|
|
375
|
+
friend std::ostream& operator<<(std::ostream& os, const reversed_iter&) {
|
|
376
|
+
return os << "<reversed>";
|
|
377
|
+
}
|
|
378
|
+
};
|
|
379
|
+
|
|
380
|
+
// Owning variant for rvalue sequences.
|
|
381
|
+
template<typename T, typename Seq>
|
|
382
|
+
class owning_reversed_iter : public next_iter_mixin<owning_reversed_iter<T, Seq>, T> {
|
|
383
|
+
Seq owned_;
|
|
384
|
+
int32_t index_;
|
|
385
|
+
public:
|
|
386
|
+
owning_reversed_iter(Seq&& seq) : owned_(std::move(seq)), index_(tpy::__len__(owned_) - 1) {}
|
|
387
|
+
|
|
388
|
+
owning_reversed_iter(owning_reversed_iter&&) = delete;
|
|
389
|
+
owning_reversed_iter& operator=(owning_reversed_iter&&) = delete;
|
|
390
|
+
|
|
391
|
+
std::expected<T, StopIteration> __next__() {
|
|
392
|
+
if (index_ < 0) return tpy::make_unexpected(StopIteration{});
|
|
393
|
+
return tpy::__getitem__(owned_, index_--);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
owning_reversed_iter& __iter__() { return *this; }
|
|
397
|
+
|
|
398
|
+
friend std::ostream& operator<<(std::ostream& os, const owning_reversed_iter&) {
|
|
399
|
+
return os << "<reversed>";
|
|
400
|
+
}
|
|
401
|
+
};
|
|
402
|
+
|
|
403
|
+
// lvalue: store reference (container outlives the loop)
|
|
404
|
+
template<typename T, typename Seq>
|
|
405
|
+
auto builtin_reversed(const Seq& seq) {
|
|
406
|
+
return reversed_iter<T, Seq>(seq);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
// rvalue: own the container
|
|
410
|
+
template<typename T, typename Seq>
|
|
411
|
+
requires (!std::is_lvalue_reference_v<Seq&&>)
|
|
412
|
+
auto builtin_reversed(Seq&& seq) {
|
|
413
|
+
return owning_reversed_iter<T, std::remove_cvref_t<Seq>>(std::move(seq));
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
// -- map --
|
|
418
|
+
|
|
419
|
+
template<typename U, typename Iter, typename Fn>
|
|
420
|
+
class map_iter : public next_iter_mixin<map_iter<U, Iter, Fn>, U> {
|
|
421
|
+
Iter iter_;
|
|
422
|
+
Fn fn_;
|
|
423
|
+
public:
|
|
424
|
+
map_iter(Iter&& iter, Fn fn)
|
|
425
|
+
: iter_(std::move(iter)), fn_(std::move(fn)) {}
|
|
426
|
+
|
|
427
|
+
std::expected<U, StopIteration> __next__() {
|
|
428
|
+
auto r = iter_.__next__();
|
|
429
|
+
if (!r.has_value()) return tpy::make_unexpected(StopIteration{});
|
|
430
|
+
return fn_(unwrap_ref(*r));
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
map_iter& __iter__() { return *this; }
|
|
434
|
+
|
|
435
|
+
friend std::ostream& operator<<(std::ostream& os, const map_iter&) {
|
|
436
|
+
return os << "<map>";
|
|
437
|
+
}
|
|
438
|
+
};
|
|
439
|
+
|
|
440
|
+
// Owning variant: moves the container in so rvalue arguments don't dangle.
|
|
441
|
+
template<typename U, typename Container, typename Fn>
|
|
442
|
+
class owning_map_iter
|
|
443
|
+
: public next_iter_mixin<owning_map_iter<U, Container, Fn>, U> {
|
|
444
|
+
using Iter = decltype(tpy::__iter__(std::declval<Container&>()));
|
|
445
|
+
Container owned_;
|
|
446
|
+
Iter iter_;
|
|
447
|
+
Fn fn_;
|
|
448
|
+
public:
|
|
449
|
+
owning_map_iter(Fn fn, Container&& c)
|
|
450
|
+
: owned_(std::move(c)), iter_(tpy::__iter__(owned_)), fn_(std::move(fn)) {}
|
|
451
|
+
|
|
452
|
+
owning_map_iter(owning_map_iter&&) = delete;
|
|
453
|
+
owning_map_iter& operator=(owning_map_iter&&) = delete;
|
|
454
|
+
|
|
455
|
+
std::expected<U, StopIteration> __next__() {
|
|
456
|
+
auto r = iter_.__next__();
|
|
457
|
+
if (!r.has_value()) return tpy::make_unexpected(StopIteration{});
|
|
458
|
+
return fn_(unwrap_ref(*r));
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
owning_map_iter& __iter__() { return *this; }
|
|
462
|
+
|
|
463
|
+
friend std::ostream& operator<<(std::ostream& os, const owning_map_iter&) {
|
|
464
|
+
return os << "<map>";
|
|
465
|
+
}
|
|
466
|
+
};
|
|
467
|
+
|
|
468
|
+
// lvalue: iterate via __iter__/__next__() protocol.
|
|
469
|
+
// T is the input element type -- unused in the body but required by the codegen
|
|
470
|
+
// template syntax (::tpy::builtin_map<{T}, {U}>).
|
|
471
|
+
template<typename T, typename U, typename Fn, typename Iterable>
|
|
472
|
+
auto builtin_map(Fn&& fn, Iterable& iterable) {
|
|
473
|
+
auto iter = tpy::__iter__(iterable);
|
|
474
|
+
return map_iter<U, decltype(iter), std::decay_t<Fn>>(
|
|
475
|
+
std::move(iter), std::forward<Fn>(fn));
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
// rvalue: own the container to prevent dangling iterators
|
|
479
|
+
template<typename T, typename U, typename Fn, typename Iterable>
|
|
480
|
+
requires (!std::is_lvalue_reference_v<Iterable&&>)
|
|
481
|
+
auto builtin_map(Fn&& fn, Iterable&& iterable) {
|
|
482
|
+
return owning_map_iter<U, std::remove_cvref_t<Iterable>, std::decay_t<Fn>>(
|
|
483
|
+
std::forward<Fn>(fn), std::move(iterable));
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
|
|
487
|
+
// -- map_multi (N-iterable, variadic) --
|
|
488
|
+
|
|
489
|
+
template<typename U, typename Fn, typename IterTuple>
|
|
490
|
+
class map_multi_iter : public next_iter_mixin<map_multi_iter<U, Fn, IterTuple>, U> {
|
|
491
|
+
IterTuple iters_;
|
|
492
|
+
Fn fn_;
|
|
493
|
+
|
|
494
|
+
template<size_t... Is>
|
|
495
|
+
std::expected<U, StopIteration> call_next(std::index_sequence<Is...>) {
|
|
496
|
+
// Brace-init guarantees left-to-right evaluation order
|
|
497
|
+
auto results = std::tuple{std::get<Is>(iters_).__next__()...};
|
|
498
|
+
if ((!std::get<Is>(results).has_value() || ...))
|
|
499
|
+
return tpy::make_unexpected(StopIteration{});
|
|
500
|
+
// static_cast forwards Own[T] args (Point&&) as rvalues, others as lvalues
|
|
501
|
+
return fn_(static_cast<detail::fn_param_t<Fn, Is>>(unwrap_ref(*std::get<Is>(results)))...);
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
public:
|
|
505
|
+
map_multi_iter(IterTuple&& iters, Fn fn)
|
|
506
|
+
: iters_(std::move(iters)), fn_(std::move(fn)) {}
|
|
507
|
+
|
|
508
|
+
std::expected<U, StopIteration> __next__() {
|
|
509
|
+
return call_next(std::make_index_sequence<std::tuple_size_v<IterTuple>>{});
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
map_multi_iter& __iter__() { return *this; }
|
|
513
|
+
|
|
514
|
+
friend std::ostream& operator<<(std::ostream& os, const map_multi_iter&) {
|
|
515
|
+
return os << "<map>";
|
|
516
|
+
}
|
|
517
|
+
};
|
|
518
|
+
|
|
519
|
+
template<typename U, typename Fn, typename... Containers>
|
|
520
|
+
class owning_map_multi_iter
|
|
521
|
+
: public next_iter_mixin<owning_map_multi_iter<U, Fn, Containers...>, U> {
|
|
522
|
+
using IterTuple = std::tuple<decltype(tpy::__iter__(std::declval<Containers&>()))...>;
|
|
523
|
+
std::tuple<Containers...> owned_;
|
|
524
|
+
IterTuple iters_;
|
|
525
|
+
Fn fn_;
|
|
526
|
+
|
|
527
|
+
template<size_t... Is>
|
|
528
|
+
static IterTuple make_iters(std::tuple<Containers...>& owned, std::index_sequence<Is...>) {
|
|
529
|
+
return IterTuple{tpy::__iter__(std::get<Is>(owned))...};
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
template<size_t... Is>
|
|
533
|
+
std::expected<U, StopIteration> call_next(std::index_sequence<Is...>) {
|
|
534
|
+
auto results = std::tuple{std::get<Is>(iters_).__next__()...};
|
|
535
|
+
if ((!std::get<Is>(results).has_value() || ...))
|
|
536
|
+
return tpy::make_unexpected(StopIteration{});
|
|
537
|
+
return fn_(static_cast<detail::fn_param_t<Fn, Is>>(unwrap_ref(*std::get<Is>(results)))...);
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
public:
|
|
541
|
+
template<typename... CCs>
|
|
542
|
+
owning_map_multi_iter(Fn fn, CCs&&... cs)
|
|
543
|
+
: owned_{std::forward<CCs>(cs)...},
|
|
544
|
+
iters_(make_iters(owned_, std::index_sequence_for<Containers...>{})),
|
|
545
|
+
fn_(std::move(fn)) {}
|
|
546
|
+
|
|
547
|
+
owning_map_multi_iter(owning_map_multi_iter&&) = delete;
|
|
548
|
+
owning_map_multi_iter& operator=(owning_map_multi_iter&&) = delete;
|
|
549
|
+
|
|
550
|
+
std::expected<U, StopIteration> __next__() {
|
|
551
|
+
return call_next(std::index_sequence_for<Containers...>{});
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
owning_map_multi_iter& __iter__() { return *this; }
|
|
555
|
+
|
|
556
|
+
friend std::ostream& operator<<(std::ostream& os, const owning_map_multi_iter&) {
|
|
557
|
+
return os << "<map>";
|
|
558
|
+
}
|
|
559
|
+
};
|
|
560
|
+
|
|
561
|
+
// Variadic factory: lvalue (all iterables are lvalue references)
|
|
562
|
+
template<typename U, typename Fn, typename... Its>
|
|
563
|
+
auto builtin_map_n(Fn&& fn, Its&... its) {
|
|
564
|
+
auto iters = std::tuple{tpy::__iter__(its)...};
|
|
565
|
+
return map_multi_iter<U, std::decay_t<Fn>, decltype(iters)>(
|
|
566
|
+
std::move(iters), std::forward<Fn>(fn));
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
// Variadic factory: rvalue (at least one iterable is an rvalue)
|
|
570
|
+
template<typename U, typename Fn, typename... Its>
|
|
571
|
+
requires ((!std::is_lvalue_reference_v<Its&&>) || ...)
|
|
572
|
+
auto builtin_map_n(Fn&& fn, Its&&... its) {
|
|
573
|
+
return owning_map_multi_iter<U, std::decay_t<Fn>, std::remove_cvref_t<Its>...>(
|
|
574
|
+
std::forward<Fn>(fn), std::forward<Its>(its)...);
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
|
|
578
|
+
// -- filter --
|
|
579
|
+
|
|
580
|
+
template<typename T, typename Iter, typename Fn>
|
|
581
|
+
class filter_iter : public next_iter_mixin<filter_iter<T, Iter, Fn>, T> {
|
|
582
|
+
Iter iter_;
|
|
583
|
+
Fn fn_;
|
|
584
|
+
public:
|
|
585
|
+
filter_iter(Iter&& iter, Fn fn)
|
|
586
|
+
: iter_(std::move(iter)), fn_(std::move(fn)) {}
|
|
587
|
+
|
|
588
|
+
std::expected<T, StopIteration> __next__() {
|
|
589
|
+
while (true) {
|
|
590
|
+
auto r = iter_.__next__();
|
|
591
|
+
if (!r.has_value()) return tpy::make_unexpected(StopIteration{});
|
|
592
|
+
auto&& elem = unwrap_ref(*r);
|
|
593
|
+
if (fn_(elem)) {
|
|
594
|
+
return elem;
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
filter_iter& __iter__() { return *this; }
|
|
600
|
+
|
|
601
|
+
friend std::ostream& operator<<(std::ostream& os, const filter_iter&) {
|
|
602
|
+
return os << "<filter>";
|
|
603
|
+
}
|
|
604
|
+
};
|
|
605
|
+
|
|
606
|
+
// Owning variant for rvalue iterables (protocol path).
|
|
607
|
+
template<typename T, typename Container, typename Fn>
|
|
608
|
+
class owning_filter_iter
|
|
609
|
+
: public next_iter_mixin<owning_filter_iter<T, Container, Fn>, T> {
|
|
610
|
+
using Iter = decltype(tpy::__iter__(std::declval<Container&>()));
|
|
611
|
+
Container owned_;
|
|
612
|
+
Iter iter_;
|
|
613
|
+
Fn fn_;
|
|
614
|
+
public:
|
|
615
|
+
owning_filter_iter(Fn fn, Container&& c)
|
|
616
|
+
: owned_(std::move(c)), iter_(tpy::__iter__(owned_)), fn_(std::move(fn)) {}
|
|
617
|
+
|
|
618
|
+
owning_filter_iter(owning_filter_iter&&) = delete;
|
|
619
|
+
owning_filter_iter& operator=(owning_filter_iter&&) = delete;
|
|
620
|
+
|
|
621
|
+
std::expected<T, StopIteration> __next__() {
|
|
622
|
+
while (true) {
|
|
623
|
+
auto r = iter_.__next__();
|
|
624
|
+
if (!r.has_value()) return tpy::make_unexpected(StopIteration{});
|
|
625
|
+
auto&& elem = unwrap_ref(*r);
|
|
626
|
+
if (fn_(elem)) {
|
|
627
|
+
return elem;
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
owning_filter_iter& __iter__() { return *this; }
|
|
633
|
+
|
|
634
|
+
friend std::ostream& operator<<(std::ostream& os, const owning_filter_iter&) {
|
|
635
|
+
return os << "<filter>";
|
|
636
|
+
}
|
|
637
|
+
};
|
|
638
|
+
|
|
639
|
+
// Direct-iteration variant: uses C++ begin/end for reference-preserving filter.
|
|
640
|
+
// Returns val_or_ref<T> so non-value types yield references into the container.
|
|
641
|
+
template<typename T, typename Container, typename Fn>
|
|
642
|
+
class filter_direct_iter
|
|
643
|
+
: public next_iter_mixin<filter_direct_iter<T, Container, Fn>, val_or_ref<T>> {
|
|
644
|
+
using CppIter = decltype(std::declval<Container&>().begin());
|
|
645
|
+
CppIter it_;
|
|
646
|
+
CppIter end_;
|
|
647
|
+
Fn fn_;
|
|
648
|
+
public:
|
|
649
|
+
filter_direct_iter(Fn fn, Container& c)
|
|
650
|
+
: it_(c.begin()), end_(c.end()), fn_(std::move(fn)) {}
|
|
651
|
+
|
|
652
|
+
std::expected<val_or_ref<T>, StopIteration> __next__() {
|
|
653
|
+
while (it_ != end_) {
|
|
654
|
+
auto& elem = *it_;
|
|
655
|
+
++it_;
|
|
656
|
+
if (fn_(elem)) {
|
|
657
|
+
return val_or_ref<T>(elem);
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
return tpy::make_unexpected(StopIteration{});
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
filter_direct_iter& __iter__() { return *this; }
|
|
664
|
+
|
|
665
|
+
friend std::ostream& operator<<(std::ostream& os, const filter_direct_iter&) {
|
|
666
|
+
return os << "<filter>";
|
|
667
|
+
}
|
|
668
|
+
};
|
|
669
|
+
|
|
670
|
+
// Owning direct-iteration variant for rvalue containers.
|
|
671
|
+
template<typename T, typename Container, typename Fn>
|
|
672
|
+
class owning_filter_direct_iter
|
|
673
|
+
: public next_iter_mixin<owning_filter_direct_iter<T, Container, Fn>, val_or_ref<T>> {
|
|
674
|
+
using CppIter = decltype(std::declval<Container&>().begin());
|
|
675
|
+
Container owned_;
|
|
676
|
+
CppIter it_;
|
|
677
|
+
CppIter end_;
|
|
678
|
+
Fn fn_;
|
|
679
|
+
public:
|
|
680
|
+
owning_filter_direct_iter(Fn fn, Container&& c)
|
|
681
|
+
: owned_(std::move(c)), it_(owned_.begin()), end_(owned_.end()),
|
|
682
|
+
fn_(std::move(fn)) {}
|
|
683
|
+
|
|
684
|
+
owning_filter_direct_iter(owning_filter_direct_iter&&) = delete;
|
|
685
|
+
owning_filter_direct_iter& operator=(owning_filter_direct_iter&&) = delete;
|
|
686
|
+
|
|
687
|
+
std::expected<val_or_ref<T>, StopIteration> __next__() {
|
|
688
|
+
while (it_ != end_) {
|
|
689
|
+
auto& elem = *it_;
|
|
690
|
+
++it_;
|
|
691
|
+
if (fn_(elem)) {
|
|
692
|
+
return val_or_ref<T>(elem);
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
return tpy::make_unexpected(StopIteration{});
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
owning_filter_direct_iter& __iter__() { return *this; }
|
|
699
|
+
|
|
700
|
+
friend std::ostream& operator<<(std::ostream& os, const owning_filter_direct_iter&) {
|
|
701
|
+
return os << "<filter>";
|
|
702
|
+
}
|
|
703
|
+
};
|
|
704
|
+
|
|
705
|
+
// lvalue: direct iteration for containers (preserves references),
|
|
706
|
+
// __iter__/__next__() fallback for TPy iterators
|
|
707
|
+
template<typename T, typename Fn, typename Iterable>
|
|
708
|
+
auto builtin_filter(Fn&& fn, Iterable& iterable) {
|
|
709
|
+
if constexpr (detail::has_begin_end<Iterable>) {
|
|
710
|
+
return filter_direct_iter<T, Iterable, std::decay_t<Fn>>(
|
|
711
|
+
std::forward<Fn>(fn), iterable);
|
|
712
|
+
} else {
|
|
713
|
+
auto iter = tpy::__iter__(iterable);
|
|
714
|
+
return filter_iter<T, decltype(iter), std::decay_t<Fn>>(
|
|
715
|
+
std::move(iter), std::forward<Fn>(fn));
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
// rvalue: own the container to prevent dangling iterators
|
|
720
|
+
template<typename T, typename Fn, typename Iterable>
|
|
721
|
+
requires (!std::is_lvalue_reference_v<Iterable&&>)
|
|
722
|
+
auto builtin_filter(Fn&& fn, Iterable&& iterable) {
|
|
723
|
+
if constexpr (detail::has_begin_end<Iterable>) {
|
|
724
|
+
return owning_filter_direct_iter<T, std::remove_cvref_t<Iterable>,
|
|
725
|
+
std::decay_t<Fn>>(
|
|
726
|
+
std::forward<Fn>(fn), std::move(iterable));
|
|
727
|
+
} else {
|
|
728
|
+
return owning_filter_iter<T, std::remove_cvref_t<Iterable>,
|
|
729
|
+
std::decay_t<Fn>>(
|
|
730
|
+
std::forward<Fn>(fn), std::move(iterable));
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
// -- filter(None, ...) -- truthy filtering via to_bool
|
|
735
|
+
|
|
736
|
+
template<typename T, typename Iterable>
|
|
737
|
+
auto builtin_filter_truthy(Iterable& iterable) {
|
|
738
|
+
auto pred = [](const auto& x) -> bool { return to_bool(x); };
|
|
739
|
+
return builtin_filter<T>(pred, iterable);
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
template<typename T, typename Iterable>
|
|
743
|
+
requires (!std::is_lvalue_reference_v<Iterable&&>)
|
|
744
|
+
auto builtin_filter_truthy(Iterable&& iterable) {
|
|
745
|
+
auto pred = [](const auto& x) -> bool { return to_bool(x); };
|
|
746
|
+
return builtin_filter<T>(pred, std::move(iterable));
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
} // namespace tpy
|