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,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TurboPython Runtime - next_iter adapter
|
|
3
|
+
*
|
|
4
|
+
* Provides begin()/end() for any type with __next__() returning
|
|
5
|
+
* std::expected<T, StopIteration>. This bridges the TPy Iterator protocol
|
|
6
|
+
* (__next__/__iter__) to C++ range-for loops.
|
|
7
|
+
*
|
|
8
|
+
* Usage: inherit from next_iter_mixin<Derived, T> to gain begin()/end().
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
#pragma once
|
|
12
|
+
|
|
13
|
+
#include "core.hpp"
|
|
14
|
+
|
|
15
|
+
#include <expected>
|
|
16
|
+
#include <tuple>
|
|
17
|
+
#include <optional>
|
|
18
|
+
|
|
19
|
+
namespace tpy {
|
|
20
|
+
|
|
21
|
+
// Unwrap val_or_ref<T> via .get(), pass through plain T unchanged.
|
|
22
|
+
template<typename T>
|
|
23
|
+
decltype(auto) unwrap_ref(T& v) {
|
|
24
|
+
if constexpr (requires { typename T::is_val_or_ref_tag; }) {
|
|
25
|
+
return v.get();
|
|
26
|
+
} else {
|
|
27
|
+
return (v);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Move-aware unwrap: moves plain values out (for expression-level unwrap
|
|
32
|
+
// where the source is temporary), returns reference for val_or_ref.
|
|
33
|
+
template<typename T>
|
|
34
|
+
decltype(auto) unwrap_ref_move(T& v) {
|
|
35
|
+
if constexpr (requires { typename T::is_val_or_ref_tag; }) {
|
|
36
|
+
return v.get();
|
|
37
|
+
} else {
|
|
38
|
+
return std::move(v);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Tuple overload: unwrap val_or_ref from each element.
|
|
43
|
+
// Produces tuple<string, Point> from tuple<string, val_or_ref<Point>>.
|
|
44
|
+
template<typename Tuple, std::size_t... Is>
|
|
45
|
+
auto unwrap_tuple_refs(Tuple& t, std::index_sequence<Is...>) {
|
|
46
|
+
return std::tuple{unwrap_ref_move(std::get<Is>(t))...};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
template<typename... Ts>
|
|
50
|
+
auto unwrap_ref_move(std::tuple<Ts...>& t) {
|
|
51
|
+
return unwrap_tuple_refs(t, std::index_sequence_for<Ts...>{});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
struct NextSentinel {};
|
|
55
|
+
|
|
56
|
+
template<typename Parent, typename T>
|
|
57
|
+
struct NextIterator {
|
|
58
|
+
Parent* parent;
|
|
59
|
+
std::optional<T> current;
|
|
60
|
+
|
|
61
|
+
NextIterator& operator++() {
|
|
62
|
+
auto r = parent->__next__();
|
|
63
|
+
current = r.has_value() ? std::optional<T>(std::move(*r)) : std::nullopt;
|
|
64
|
+
return *this;
|
|
65
|
+
}
|
|
66
|
+
decltype(auto) operator*() { return unwrap_ref(*current); }
|
|
67
|
+
decltype(auto) operator*() const { return unwrap_ref(*current); }
|
|
68
|
+
bool operator!=(NextSentinel) const { return current.has_value(); }
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
// CRTP mixin: adds begin()/end() to any class with __next__().
|
|
72
|
+
template<typename Derived, typename T>
|
|
73
|
+
struct next_iter_mixin {
|
|
74
|
+
NextIterator<Derived, T> begin() {
|
|
75
|
+
NextIterator<Derived, T> it{static_cast<Derived*>(this), std::nullopt};
|
|
76
|
+
++it; // prime with first element
|
|
77
|
+
return it;
|
|
78
|
+
}
|
|
79
|
+
NextSentinel end() { return {}; }
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
} // namespace tpy
|
|
@@ -0,0 +1,518 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TurboPython Runtime - Ordered Map
|
|
3
|
+
*
|
|
4
|
+
* Hash map that preserves insertion order (matching Python 3.7+ dict semantics).
|
|
5
|
+
* Combines std::unordered_map for O(1) lookup with an intrusive doubly-linked
|
|
6
|
+
* list for insertion-order iteration.
|
|
7
|
+
*
|
|
8
|
+
* Default iteration yields keys only (matching Python's `for k in d`).
|
|
9
|
+
* Use items_begin()/items_end() for key-value pair iteration.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
#pragma once
|
|
13
|
+
|
|
14
|
+
#include <cstdint>
|
|
15
|
+
#include <expected>
|
|
16
|
+
#include <functional>
|
|
17
|
+
#include <initializer_list>
|
|
18
|
+
#include <tuple>
|
|
19
|
+
#include <unordered_map>
|
|
20
|
+
#include <utility>
|
|
21
|
+
|
|
22
|
+
#include "core.hpp"
|
|
23
|
+
|
|
24
|
+
namespace tpy {
|
|
25
|
+
|
|
26
|
+
template<typename K, typename V>
|
|
27
|
+
class ordered_map {
|
|
28
|
+
struct Node {
|
|
29
|
+
K key;
|
|
30
|
+
V value;
|
|
31
|
+
Node* prev = nullptr;
|
|
32
|
+
Node* next = nullptr;
|
|
33
|
+
|
|
34
|
+
template<typename KK, typename VV>
|
|
35
|
+
Node(KK&& k, VV&& v)
|
|
36
|
+
: key(std::forward<KK>(k)), value(std::forward<VV>(v)) {}
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
public:
|
|
40
|
+
// -- Key iterator (default -- matches Python's `for k in d`) ------------
|
|
41
|
+
|
|
42
|
+
template<bool IsConst>
|
|
43
|
+
class key_iterator_impl {
|
|
44
|
+
friend class ordered_map;
|
|
45
|
+
using NodePtr = std::conditional_t<IsConst, const Node*, Node*>;
|
|
46
|
+
NodePtr node_;
|
|
47
|
+
|
|
48
|
+
explicit key_iterator_impl(NodePtr n) : node_(n) {}
|
|
49
|
+
|
|
50
|
+
public:
|
|
51
|
+
// Required by std::forward_iterator (std::default_initializable)
|
|
52
|
+
key_iterator_impl() : node_(nullptr) {}
|
|
53
|
+
|
|
54
|
+
using iterator_category = std::forward_iterator_tag;
|
|
55
|
+
using difference_type = std::ptrdiff_t;
|
|
56
|
+
using value_type = K;
|
|
57
|
+
using reference = const K&;
|
|
58
|
+
|
|
59
|
+
const K& operator*() const { return node_->key; }
|
|
60
|
+
|
|
61
|
+
key_iterator_impl& operator++() { node_ = node_->next; return *this; }
|
|
62
|
+
key_iterator_impl operator++(int) { auto tmp = *this; node_ = node_->next; return tmp; }
|
|
63
|
+
|
|
64
|
+
bool operator==(const key_iterator_impl& o) const { return node_ == o.node_; }
|
|
65
|
+
bool operator!=(const key_iterator_impl& o) const { return node_ != o.node_; }
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
// -- Items iterator (for .items() / internal use) -----------------------
|
|
69
|
+
|
|
70
|
+
template<bool IsConst>
|
|
71
|
+
class items_iterator_impl {
|
|
72
|
+
friend class ordered_map;
|
|
73
|
+
using NodePtr = std::conditional_t<IsConst, const Node*, Node*>;
|
|
74
|
+
NodePtr node_;
|
|
75
|
+
|
|
76
|
+
explicit items_iterator_impl(NodePtr n) : node_(n) {}
|
|
77
|
+
|
|
78
|
+
public:
|
|
79
|
+
using iterator_category = std::forward_iterator_tag;
|
|
80
|
+
using difference_type = std::ptrdiff_t;
|
|
81
|
+
// Proxy pair: references into Node data, returned by value.
|
|
82
|
+
// Safe for range-for with auto&& structured bindings.
|
|
83
|
+
using value_type = std::pair<const K&,
|
|
84
|
+
std::conditional_t<IsConst, const V&, V&>>;
|
|
85
|
+
|
|
86
|
+
value_type operator*() const { return {node_->key, node_->value}; }
|
|
87
|
+
|
|
88
|
+
items_iterator_impl& operator++() { node_ = node_->next; return *this; }
|
|
89
|
+
items_iterator_impl operator++(int) { auto tmp = *this; node_ = node_->next; return tmp; }
|
|
90
|
+
|
|
91
|
+
bool operator==(const items_iterator_impl& o) const { return node_ == o.node_; }
|
|
92
|
+
bool operator!=(const items_iterator_impl& o) const { return node_ != o.node_; }
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
// -- Value iterator (for .values()) -------------------------------------
|
|
96
|
+
|
|
97
|
+
template<bool IsConst>
|
|
98
|
+
class value_iterator_impl {
|
|
99
|
+
friend class ordered_map;
|
|
100
|
+
using NodePtr = std::conditional_t<IsConst, const Node*, Node*>;
|
|
101
|
+
NodePtr node_;
|
|
102
|
+
|
|
103
|
+
explicit value_iterator_impl(NodePtr n) : node_(n) {}
|
|
104
|
+
|
|
105
|
+
public:
|
|
106
|
+
// Required by std::forward_iterator (std::default_initializable)
|
|
107
|
+
value_iterator_impl() : node_(nullptr) {}
|
|
108
|
+
|
|
109
|
+
using iterator_category = std::forward_iterator_tag;
|
|
110
|
+
using difference_type = std::ptrdiff_t;
|
|
111
|
+
using value_type = V;
|
|
112
|
+
using reference = std::conditional_t<IsConst, const V&, V&>;
|
|
113
|
+
|
|
114
|
+
reference operator*() const { return node_->value; }
|
|
115
|
+
|
|
116
|
+
value_iterator_impl& operator++() { node_ = node_->next; return *this; }
|
|
117
|
+
value_iterator_impl operator++(int) { auto tmp = *this; node_ = node_->next; return tmp; }
|
|
118
|
+
|
|
119
|
+
bool operator==(const value_iterator_impl& o) const { return node_ == o.node_; }
|
|
120
|
+
bool operator!=(const value_iterator_impl& o) const { return node_ != o.node_; }
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
// -- Tuple-items iterator (yields std::tuple<K,V> for tuple unpacking) ---
|
|
124
|
+
|
|
125
|
+
template<bool IsConst>
|
|
126
|
+
class tuple_items_iterator_impl {
|
|
127
|
+
friend class ordered_map;
|
|
128
|
+
using NodePtr = std::conditional_t<IsConst, const Node*, Node*>;
|
|
129
|
+
NodePtr node_;
|
|
130
|
+
|
|
131
|
+
explicit tuple_items_iterator_impl(NodePtr n) : node_(n) {}
|
|
132
|
+
|
|
133
|
+
public:
|
|
134
|
+
// Required by std::forward_iterator (std::default_initializable)
|
|
135
|
+
tuple_items_iterator_impl() : node_(nullptr) {}
|
|
136
|
+
|
|
137
|
+
using iterator_category = std::forward_iterator_tag;
|
|
138
|
+
using difference_type = std::ptrdiff_t;
|
|
139
|
+
using value_type = std::tuple<K, V>;
|
|
140
|
+
using reference = value_type;
|
|
141
|
+
|
|
142
|
+
value_type operator*() const { return {node_->key, node_->value}; }
|
|
143
|
+
|
|
144
|
+
tuple_items_iterator_impl& operator++() { node_ = node_->next; return *this; }
|
|
145
|
+
tuple_items_iterator_impl operator++(int) { auto tmp = *this; node_ = node_->next; return tmp; }
|
|
146
|
+
|
|
147
|
+
bool operator==(const tuple_items_iterator_impl& o) const { return node_ == o.node_; }
|
|
148
|
+
bool operator!=(const tuple_items_iterator_impl& o) const { return node_ != o.node_; }
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
using iterator = key_iterator_impl<false>;
|
|
152
|
+
using const_iterator = key_iterator_impl<true>;
|
|
153
|
+
using items_iterator = items_iterator_impl<false>;
|
|
154
|
+
using const_items_iterator = items_iterator_impl<true>;
|
|
155
|
+
using const_value_iterator = value_iterator_impl<true>;
|
|
156
|
+
using const_tuple_items_iterator = tuple_items_iterator_impl<true>;
|
|
157
|
+
|
|
158
|
+
// -- Construction -------------------------------------------------------
|
|
159
|
+
|
|
160
|
+
ordered_map() = default;
|
|
161
|
+
|
|
162
|
+
ordered_map(std::initializer_list<std::tuple<K, V>> init) {
|
|
163
|
+
for (auto& t : init) {
|
|
164
|
+
insert_or_assign(std::get<0>(t), std::get<1>(t));
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
ordered_map(const ordered_map& other) {
|
|
169
|
+
for (auto* n = other.head_; n != nullptr; n = n->next) {
|
|
170
|
+
insert_or_assign(n->key, n->value);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
ordered_map(ordered_map&& other) noexcept
|
|
175
|
+
: table_(std::move(other.table_))
|
|
176
|
+
, head_(other.head_)
|
|
177
|
+
, tail_(other.tail_)
|
|
178
|
+
{
|
|
179
|
+
other.head_ = nullptr;
|
|
180
|
+
other.tail_ = nullptr;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
ordered_map& operator=(const ordered_map& other) {
|
|
184
|
+
if (this != &other) {
|
|
185
|
+
clear();
|
|
186
|
+
for (auto* n = other.head_; n != nullptr; n = n->next) {
|
|
187
|
+
insert_or_assign(n->key, n->value);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return *this;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
ordered_map& operator=(ordered_map&& other) noexcept {
|
|
194
|
+
if (this != &other) {
|
|
195
|
+
clear();
|
|
196
|
+
table_ = std::move(other.table_);
|
|
197
|
+
head_ = other.head_;
|
|
198
|
+
tail_ = other.tail_;
|
|
199
|
+
other.head_ = nullptr;
|
|
200
|
+
other.tail_ = nullptr;
|
|
201
|
+
}
|
|
202
|
+
return *this;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
~ordered_map() {
|
|
206
|
+
clear();
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// -- Element access -----------------------------------------------------
|
|
210
|
+
|
|
211
|
+
// Inserts V{} on missing key (std::map semantics, NOT Python semantics).
|
|
212
|
+
// Not used by generated code; provided for standalone C++ use.
|
|
213
|
+
V& operator[](const K& key) {
|
|
214
|
+
auto it = table_.find(key);
|
|
215
|
+
if (it != table_.end()) {
|
|
216
|
+
return it->second->value;
|
|
217
|
+
}
|
|
218
|
+
auto* node = new Node(key, V{});
|
|
219
|
+
link_back(node);
|
|
220
|
+
table_.emplace(key, node);
|
|
221
|
+
return node->value;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// -- Capacity -----------------------------------------------------------
|
|
225
|
+
|
|
226
|
+
int32_t size() const { return static_cast<int32_t>(table_.size()); }
|
|
227
|
+
bool empty() const { return table_.empty(); }
|
|
228
|
+
|
|
229
|
+
// -- Modifiers ----------------------------------------------------------
|
|
230
|
+
|
|
231
|
+
template<typename KK, typename VV>
|
|
232
|
+
void insert_or_assign(KK&& key, VV&& value) {
|
|
233
|
+
auto it = table_.find(key);
|
|
234
|
+
if (it != table_.end()) {
|
|
235
|
+
it->second->value = std::forward<VV>(value);
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
auto* node = new Node(std::forward<KK>(key), std::forward<VV>(value));
|
|
239
|
+
link_back(node);
|
|
240
|
+
table_.emplace(node->key, node);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
bool erase(const K& key) {
|
|
244
|
+
auto it = table_.find(key);
|
|
245
|
+
if (it == table_.end()) return false;
|
|
246
|
+
Node* node = it->second;
|
|
247
|
+
table_.erase(it);
|
|
248
|
+
unlink(node);
|
|
249
|
+
delete node;
|
|
250
|
+
return true;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
void erase(items_iterator pos) {
|
|
254
|
+
Node* node = pos.node_;
|
|
255
|
+
table_.erase(node->key);
|
|
256
|
+
unlink(node);
|
|
257
|
+
delete node;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
void clear() {
|
|
261
|
+
auto* n = head_;
|
|
262
|
+
while (n != nullptr) {
|
|
263
|
+
auto* next = n->next;
|
|
264
|
+
delete n;
|
|
265
|
+
n = next;
|
|
266
|
+
}
|
|
267
|
+
table_.clear();
|
|
268
|
+
head_ = nullptr;
|
|
269
|
+
tail_ = nullptr;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// -- Lookup -------------------------------------------------------------
|
|
273
|
+
|
|
274
|
+
bool contains(const K& key) const {
|
|
275
|
+
return table_.find(key) != table_.end();
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
items_iterator find(const K& key) {
|
|
279
|
+
auto it = table_.find(key);
|
|
280
|
+
if (it == table_.end()) return items_end();
|
|
281
|
+
return items_iterator(it->second);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
const_items_iterator find(const K& key) const {
|
|
285
|
+
auto it = table_.find(key);
|
|
286
|
+
if (it == table_.end()) return items_end();
|
|
287
|
+
return const_items_iterator(it->second);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// -- Iteration (insertion order) ----------------------------------------
|
|
291
|
+
|
|
292
|
+
// Default: iterate keys (matches Python's `for k in d`)
|
|
293
|
+
iterator begin() { return iterator(head_); }
|
|
294
|
+
iterator end() { return iterator(nullptr); }
|
|
295
|
+
const_iterator begin() const { return const_iterator(head_); }
|
|
296
|
+
const_iterator end() const { return const_iterator(nullptr); }
|
|
297
|
+
|
|
298
|
+
// Items: iterate key-value pairs (for .items() and internal use)
|
|
299
|
+
items_iterator items_begin() { return items_iterator(head_); }
|
|
300
|
+
items_iterator items_end() { return items_iterator(nullptr); }
|
|
301
|
+
const_items_iterator items_begin() const { return const_items_iterator(head_); }
|
|
302
|
+
const_items_iterator items_end() const { return const_items_iterator(nullptr); }
|
|
303
|
+
|
|
304
|
+
// Values: iterate values only (for .values())
|
|
305
|
+
const_value_iterator values_begin() const { return const_value_iterator(head_); }
|
|
306
|
+
const_value_iterator values_end() const { return const_value_iterator(nullptr); }
|
|
307
|
+
|
|
308
|
+
// Tuple-items: iterate as std::tuple<K,V> (for Python-style `for k, v in d.items()`)
|
|
309
|
+
const_tuple_items_iterator tuple_items_begin() const { return const_tuple_items_iterator(head_); }
|
|
310
|
+
const_tuple_items_iterator tuple_items_end() const { return const_tuple_items_iterator(nullptr); }
|
|
311
|
+
|
|
312
|
+
// -- Python __iter__() support (returns native_iterator for Iterable[K]) -
|
|
313
|
+
|
|
314
|
+
// Defined in dict_ops.hpp (needs native_iterator template)
|
|
315
|
+
inline auto __iter__() const;
|
|
316
|
+
|
|
317
|
+
// -- Comparison (order-independent, matching Python) --------------------
|
|
318
|
+
|
|
319
|
+
bool operator==(const ordered_map& other) const {
|
|
320
|
+
if (table_.size() != other.table_.size()) return false;
|
|
321
|
+
for (auto* n = head_; n != nullptr; n = n->next) {
|
|
322
|
+
auto it = other.table_.find(n->key);
|
|
323
|
+
if (it == other.table_.end()) return false;
|
|
324
|
+
if (!(n->value == it->second->value)) return false;
|
|
325
|
+
}
|
|
326
|
+
return true;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
bool operator!=(const ordered_map& other) const {
|
|
330
|
+
return !(*this == other);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
private:
|
|
334
|
+
void link_back(Node* node) {
|
|
335
|
+
node->prev = tail_;
|
|
336
|
+
node->next = nullptr;
|
|
337
|
+
if (tail_) {
|
|
338
|
+
tail_->next = node;
|
|
339
|
+
} else {
|
|
340
|
+
head_ = node;
|
|
341
|
+
}
|
|
342
|
+
tail_ = node;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
void unlink(Node* node) {
|
|
346
|
+
if (node->prev) {
|
|
347
|
+
node->prev->next = node->next;
|
|
348
|
+
} else {
|
|
349
|
+
head_ = node->next;
|
|
350
|
+
}
|
|
351
|
+
if (node->next) {
|
|
352
|
+
node->next->prev = node->prev;
|
|
353
|
+
} else {
|
|
354
|
+
tail_ = node->prev;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
template<typename, typename> friend struct OwnIterDict;
|
|
359
|
+
template<typename, typename> friend struct OwnIterDictItems;
|
|
360
|
+
|
|
361
|
+
std::unordered_map<K, Node*> table_;
|
|
362
|
+
Node* head_ = nullptr;
|
|
363
|
+
Node* tail_ = nullptr;
|
|
364
|
+
};
|
|
365
|
+
|
|
366
|
+
namespace detail {
|
|
367
|
+
|
|
368
|
+
template<typename K, typename V>
|
|
369
|
+
inline void make_ordered_map_impl(ordered_map<K, V>&) {}
|
|
370
|
+
|
|
371
|
+
template<typename K, typename V, typename KK, typename VV, typename... Rest>
|
|
372
|
+
void make_ordered_map_impl(ordered_map<K, V>& m, KK&& k, VV&& v, Rest&&... rest) {
|
|
373
|
+
m.insert_or_assign(std::forward<KK>(k), std::forward<VV>(v));
|
|
374
|
+
make_ordered_map_impl<K, V>(m, std::forward<Rest>(rest)...);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
} // namespace detail
|
|
378
|
+
|
|
379
|
+
// Construct an ordered_map from move-only K or V types. Mirrors make_vector:
|
|
380
|
+
// the initializer_list ctor stores elements as const, forcing a copy of V --
|
|
381
|
+
// this helper forwards each pair into insert_or_assign so move-only values
|
|
382
|
+
// (e.g. Rc[T], Box[T]) and keys work in dict literals.
|
|
383
|
+
template<typename K, typename V, typename... Args>
|
|
384
|
+
ordered_map<K, V> make_ordered_map(Args&&... args) {
|
|
385
|
+
static_assert(sizeof...(Args) % 2 == 0,
|
|
386
|
+
"make_ordered_map requires an even number of arguments (key/value pairs)");
|
|
387
|
+
ordered_map<K, V> m;
|
|
388
|
+
detail::make_ordered_map_impl<K, V>(m, std::forward<Args>(args)...);
|
|
389
|
+
return m;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
// ---------------------------------------------------------------------------
|
|
393
|
+
// OwnIterDict -- drain iterator for ordered_map keys
|
|
394
|
+
//
|
|
395
|
+
// Owns a moved ordered_map and yields keys by move.
|
|
396
|
+
// ---------------------------------------------------------------------------
|
|
397
|
+
|
|
398
|
+
template<typename K, typename V>
|
|
399
|
+
struct OwnIterDict {
|
|
400
|
+
ordered_map<K, V> data;
|
|
401
|
+
typename ordered_map<K, V>::Node* pos;
|
|
402
|
+
|
|
403
|
+
explicit OwnIterDict(ordered_map<K, V>&& m)
|
|
404
|
+
: data(std::move(m)), pos(data.head_) {}
|
|
405
|
+
|
|
406
|
+
OwnIterDict(const OwnIterDict&) = delete;
|
|
407
|
+
OwnIterDict& operator=(const OwnIterDict&) = delete;
|
|
408
|
+
OwnIterDict(OwnIterDict&&) = default;
|
|
409
|
+
OwnIterDict& operator=(OwnIterDict&&) = default;
|
|
410
|
+
|
|
411
|
+
struct move_iter {
|
|
412
|
+
using Node = typename ordered_map<K, V>::Node;
|
|
413
|
+
Node* node_;
|
|
414
|
+
|
|
415
|
+
using iterator_category = std::input_iterator_tag;
|
|
416
|
+
using value_type = K;
|
|
417
|
+
using difference_type = std::ptrdiff_t;
|
|
418
|
+
using reference = K&&;
|
|
419
|
+
|
|
420
|
+
move_iter() : node_(nullptr) {}
|
|
421
|
+
explicit move_iter(Node* n) : node_(n) {}
|
|
422
|
+
|
|
423
|
+
K&& operator*() { return std::move(node_->key); }
|
|
424
|
+
move_iter& operator++() { node_ = node_->next; return *this; }
|
|
425
|
+
move_iter operator++(int) { auto tmp = *this; ++*this; return tmp; }
|
|
426
|
+
bool operator==(const move_iter& o) const { return node_ == o.node_; }
|
|
427
|
+
bool operator!=(const move_iter& o) const { return node_ != o.node_; }
|
|
428
|
+
};
|
|
429
|
+
|
|
430
|
+
// Do not mix range-based (begin/end) and __next__-based iteration on the
|
|
431
|
+
// same instance -- both advance shared state and the result is undefined.
|
|
432
|
+
move_iter begin() { return move_iter(pos); }
|
|
433
|
+
move_iter end() { return move_iter(nullptr); }
|
|
434
|
+
|
|
435
|
+
std::expected<K, StopIteration> __next__() {
|
|
436
|
+
if (pos == nullptr) return tpy::make_unexpected(StopIteration{});
|
|
437
|
+
K key = std::move(pos->key);
|
|
438
|
+
pos = pos->next;
|
|
439
|
+
return key;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
OwnIterDict& __iter__() { return *this; }
|
|
443
|
+
|
|
444
|
+
friend std::ostream& operator<<(std::ostream& os, const OwnIterDict&) {
|
|
445
|
+
return os << "<own_iter_dict>";
|
|
446
|
+
}
|
|
447
|
+
};
|
|
448
|
+
|
|
449
|
+
template<typename K, typename V>
|
|
450
|
+
OwnIterDict<K, V> own_iter_dict(ordered_map<K, V>&& m) {
|
|
451
|
+
return OwnIterDict<K, V>{std::move(m)};
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
// ---------------------------------------------------------------------------
|
|
455
|
+
// OwnIterDictItems -- drain iterator for ordered_map items (key-value pairs)
|
|
456
|
+
//
|
|
457
|
+
// Owns a moved ordered_map and yields std::tuple<K, V> by move.
|
|
458
|
+
// ---------------------------------------------------------------------------
|
|
459
|
+
|
|
460
|
+
template<typename K, typename V>
|
|
461
|
+
struct OwnIterDictItems {
|
|
462
|
+
ordered_map<K, V> data;
|
|
463
|
+
typename ordered_map<K, V>::Node* pos;
|
|
464
|
+
|
|
465
|
+
explicit OwnIterDictItems(ordered_map<K, V>&& m)
|
|
466
|
+
: data(std::move(m)), pos(data.head_) {}
|
|
467
|
+
|
|
468
|
+
OwnIterDictItems(const OwnIterDictItems&) = delete;
|
|
469
|
+
OwnIterDictItems& operator=(const OwnIterDictItems&) = delete;
|
|
470
|
+
OwnIterDictItems(OwnIterDictItems&&) = default;
|
|
471
|
+
OwnIterDictItems& operator=(OwnIterDictItems&&) = default;
|
|
472
|
+
|
|
473
|
+
struct move_iter {
|
|
474
|
+
using Node = typename ordered_map<K, V>::Node;
|
|
475
|
+
Node* node_;
|
|
476
|
+
|
|
477
|
+
using iterator_category = std::input_iterator_tag;
|
|
478
|
+
using value_type = std::tuple<K, V>;
|
|
479
|
+
using difference_type = std::ptrdiff_t;
|
|
480
|
+
using reference = std::tuple<K, V>;
|
|
481
|
+
|
|
482
|
+
move_iter() : node_(nullptr) {}
|
|
483
|
+
explicit move_iter(Node* n) : node_(n) {}
|
|
484
|
+
|
|
485
|
+
std::tuple<K, V> operator*() {
|
|
486
|
+
return std::tuple<K, V>(std::move(node_->key), std::move(node_->value));
|
|
487
|
+
}
|
|
488
|
+
move_iter& operator++() { node_ = node_->next; return *this; }
|
|
489
|
+
move_iter operator++(int) { auto tmp = *this; ++*this; return tmp; }
|
|
490
|
+
bool operator==(const move_iter& o) const { return node_ == o.node_; }
|
|
491
|
+
bool operator!=(const move_iter& o) const { return node_ != o.node_; }
|
|
492
|
+
};
|
|
493
|
+
|
|
494
|
+
// Do not mix range-based (begin/end) and __next__-based iteration on the
|
|
495
|
+
// same instance -- both advance shared state and the result is undefined.
|
|
496
|
+
move_iter begin() { return move_iter(pos); }
|
|
497
|
+
move_iter end() { return move_iter(nullptr); }
|
|
498
|
+
|
|
499
|
+
std::expected<std::tuple<K, V>, StopIteration> __next__() {
|
|
500
|
+
if (pos == nullptr) return tpy::make_unexpected(StopIteration{});
|
|
501
|
+
auto item = std::tuple<K, V>(std::move(pos->key), std::move(pos->value));
|
|
502
|
+
pos = pos->next;
|
|
503
|
+
return item;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
OwnIterDictItems& __iter__() { return *this; }
|
|
507
|
+
|
|
508
|
+
friend std::ostream& operator<<(std::ostream& os, const OwnIterDictItems&) {
|
|
509
|
+
return os << "<own_iter_dict_items>";
|
|
510
|
+
}
|
|
511
|
+
};
|
|
512
|
+
|
|
513
|
+
template<typename K, typename V>
|
|
514
|
+
OwnIterDictItems<K, V> own_iter_dict_items(ordered_map<K, V>&& m) {
|
|
515
|
+
return OwnIterDictItems<K, V>{std::move(m)};
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
} // namespace tpy
|