IncludeCPP 3.7.20__py3-none-any.whl → 3.7.22__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.
includecpp/__init__.py CHANGED
@@ -2,7 +2,7 @@ from .core.cpp_api import CppApi
2
2
  from .core import cssl_bridge as CSSL
3
3
  import warnings
4
4
 
5
- __version__ = "3.7.20"
5
+ __version__ = "3.7.22"
6
6
  __all__ = ["CppApi", "CSSL"]
7
7
 
8
8
  # Module-level cache for C++ modules
@@ -7720,7 +7720,13 @@ def cssl_doc(search, list_sections):
7720
7720
  click.echo("Or use: includecpp cssl doc --list")
7721
7721
  else:
7722
7722
  # Full documentation mode
7723
- click.echo_via_pager(content)
7723
+ # Replace Unicode characters that may not be supported on all terminals
7724
+ safe_content = content.replace('✓', '[OK]').replace('✗', '[X]').replace('→', '->').replace('←', '<-').replace('•', '*').replace('─', '-').replace('│', '|').replace('└', '+').replace('├', '+').replace('▸', '>').replace('▾', 'v')
7725
+ try:
7726
+ click.echo_via_pager(safe_content)
7727
+ except UnicodeEncodeError:
7728
+ # Fallback: encode with errors='replace'
7729
+ click.echo(safe_content.encode('ascii', errors='replace').decode('ascii'))
7724
7730
  else:
7725
7731
  click.secho("Documentation file not found.", fg='yellow')
7726
7732
  click.echo("Looking for: CSSL_DOCUMENTATION.md")
@@ -307,6 +307,10 @@ class CSSLBuiltins:
307
307
  self._functions['dataspace'] = self.builtin_dataspace
308
308
  self._functions['openquote'] = self.builtin_openquote
309
309
  self._functions['OpenFind'] = self.builtin_openfind
310
+ self._functions['vector'] = self.builtin_vector
311
+ self._functions['array'] = self.builtin_array
312
+ self._functions['stack'] = self.builtin_stack
313
+ self._functions['map'] = self.builtin_map
310
314
 
311
315
  # Print aliases for CSSL
312
316
  self._functions['printl'] = self.builtin_println # CSSL uses printl for println
@@ -433,13 +437,50 @@ class CSSLBuiltins:
433
437
  # ============= Type Checking =============
434
438
 
435
439
  def builtin_typeof(self, value: Any) -> str:
436
- """Get type name"""
440
+ """Get type name - returns CSSL-specific type names for CSSL types"""
437
441
  if value is None:
438
442
  return 'null'
443
+
444
+ # Check CSSL-specific types first
445
+ from .cssl_types import (Vector, Array, Stack, DataStruct,
446
+ List as CSSLList, Dictionary, Map,
447
+ Shuffled, Iterator, Combo, DataSpace,
448
+ OpenQuote, Parameter, CSSLInstance)
449
+
450
+ if isinstance(value, Vector):
451
+ return 'vector'
452
+ elif isinstance(value, Array):
453
+ return 'array'
454
+ elif isinstance(value, Stack):
455
+ return 'stack'
456
+ elif isinstance(value, DataStruct):
457
+ return 'datastruct'
458
+ elif isinstance(value, CSSLList):
459
+ return 'list'
460
+ elif isinstance(value, Dictionary):
461
+ return 'dictionary'
462
+ elif isinstance(value, Map):
463
+ return 'map'
464
+ elif isinstance(value, Shuffled):
465
+ return 'shuffled'
466
+ elif isinstance(value, Iterator):
467
+ return 'iterator'
468
+ elif isinstance(value, Combo):
469
+ return 'combo'
470
+ elif isinstance(value, DataSpace):
471
+ return 'dataspace'
472
+ elif isinstance(value, OpenQuote):
473
+ return 'openquote'
474
+ elif isinstance(value, Parameter):
475
+ return 'parameter'
476
+ elif isinstance(value, CSSLInstance):
477
+ return value._class.name
478
+
479
+ # Python types as fallback
439
480
  type_map = {
440
481
  int: 'int',
441
482
  float: 'float',
442
- str: 'str',
483
+ str: 'string',
443
484
  bool: 'bool',
444
485
  list: 'list',
445
486
  dict: 'dict',
@@ -2322,6 +2363,38 @@ class CSSLBuiltins:
2322
2363
  from .cssl_types import OpenQuote
2323
2364
  return OpenQuote(db_ref)
2324
2365
 
2366
+ def builtin_vector(self, element_type: str = 'dynamic') -> Any:
2367
+ """Create a vector container.
2368
+
2369
+ Usage: vector<int> myVector; or vector('int')
2370
+ """
2371
+ from .cssl_types import Vector
2372
+ return Vector(element_type)
2373
+
2374
+ def builtin_array(self, element_type: str = 'dynamic') -> Any:
2375
+ """Create an array container.
2376
+
2377
+ Usage: array<string> myArray; or array('string')
2378
+ """
2379
+ from .cssl_types import Array
2380
+ return Array(element_type)
2381
+
2382
+ def builtin_stack(self, element_type: str = 'dynamic') -> Any:
2383
+ """Create a stack container.
2384
+
2385
+ Usage: stack<int> myStack; or stack('int')
2386
+ """
2387
+ from .cssl_types import Stack
2388
+ return Stack(element_type)
2389
+
2390
+ def builtin_map(self, key_type: str = 'dynamic', value_type: str = 'dynamic') -> Any:
2391
+ """Create a map container.
2392
+
2393
+ Usage: map<string, int> myMap; or map('string', 'int')
2394
+ """
2395
+ from .cssl_types import Map
2396
+ return Map(key_type, value_type)
2397
+
2325
2398
  def builtin_openfind(self, combo_or_type: Any, index: int = 0, params: list = None) -> Any:
2326
2399
  """Find open parameter by type or combo space.
2327
2400
 
@@ -252,8 +252,15 @@ class CSSLLexer:
252
252
  # $<name> shared object reference
253
253
  self._read_shared_ref()
254
254
  elif char == '%':
255
- # %<name> captured reference (for infusion)
256
- self._read_captured_ref()
255
+ # Check if this is %<name> captured reference or % modulo operator
256
+ next_char = self._peek(1)
257
+ if next_char and (next_char.isalpha() or next_char == '_'):
258
+ # %<name> captured reference (for infusion)
259
+ self._read_captured_ref()
260
+ else:
261
+ # % modulo operator
262
+ self._add_token(TokenType.MODULO, '%')
263
+ self._advance()
257
264
  elif char == '&':
258
265
  # & for references
259
266
  if self._peek(1) == '&':
@@ -321,9 +328,6 @@ class CSSLLexer:
321
328
  else:
322
329
  # Already handled by // comment check above, but just in case
323
330
  self._skip_comment()
324
- elif char == '%':
325
- self._add_token(TokenType.MODULO, '%')
326
- self._advance()
327
331
  elif char == '<':
328
332
  self._read_less_than()
329
333
  elif char == '>':
@@ -848,7 +852,7 @@ class CSSLParser:
848
852
  if self._match_keyword('open'):
849
853
  param_info['open'] = True
850
854
 
851
- # Handle type annotations
855
+ # Handle type annotations (builtin types like int, string, etc.)
852
856
  if self._check(TokenType.KEYWORD) and self._is_type_keyword(self._current().value):
853
857
  param_info['type'] = self._advance().value
854
858
 
@@ -872,6 +876,39 @@ class CSSLParser:
872
876
  self._advance()
873
877
  param_info['generic'] = ''.join(generic_parts)
874
878
 
879
+ # Handle custom class types (identifier followed by another identifier = type + name)
880
+ elif self._check(TokenType.IDENTIFIER):
881
+ # Look ahead: if next token is also an identifier, current is the type
882
+ saved_pos = self.pos
883
+ potential_type = self._advance().value
884
+
885
+ # Check for generic type parameter <T> on custom type
886
+ if self._check(TokenType.COMPARE_LT):
887
+ self._advance()
888
+ generic_parts = []
889
+ depth = 1
890
+ while depth > 0 and not self._is_at_end():
891
+ if self._check(TokenType.COMPARE_LT):
892
+ depth += 1
893
+ generic_parts.append('<')
894
+ elif self._check(TokenType.COMPARE_GT):
895
+ depth -= 1
896
+ if depth > 0:
897
+ generic_parts.append('>')
898
+ elif self._check(TokenType.COMMA):
899
+ generic_parts.append(',')
900
+ else:
901
+ generic_parts.append(self._current().value)
902
+ self._advance()
903
+ param_info['generic'] = ''.join(generic_parts)
904
+
905
+ # If followed by identifier, this is "Type name" pattern
906
+ if self._check(TokenType.IDENTIFIER):
907
+ param_info['type'] = potential_type
908
+ else:
909
+ # Not a type, restore position - this is just a param name
910
+ self.pos = saved_pos
911
+
875
912
  # Handle reference operator &
876
913
  if self._match(TokenType.AMPERSAND):
877
914
  param_info['ref'] = True
@@ -2509,6 +2546,20 @@ class CSSLParser:
2509
2546
 
2510
2547
  self._expect(TokenType.BLOCK_END) # consume }
2511
2548
 
2549
+ # Check for array-style initialization: vector<int>[1, 2, 3], array<string>["a", "b"]
2550
+ elif self._check(TokenType.BRACKET_START):
2551
+ self._advance() # consume [
2552
+ init_values = []
2553
+
2554
+ while not self._check(TokenType.BRACKET_END) and not self._is_at_end():
2555
+ init_values.append(self._parse_expression())
2556
+
2557
+ # Optional comma
2558
+ if self._check(TokenType.COMMA):
2559
+ self._advance()
2560
+
2561
+ self._expect(TokenType.BRACKET_END) # consume ]
2562
+
2512
2563
  return ASTNode('type_instantiation', value={
2513
2564
  'type': name,
2514
2565
  'element_type': element_type,
@@ -830,8 +830,18 @@ class CSSLRuntime:
830
830
  if hasattr(instance, 'append'):
831
831
  instance.append(init_value)
832
832
 
833
+ # Check for global modifier
834
+ modifiers = decl.get('modifiers', [])
835
+ is_global = 'global' in modifiers
836
+
833
837
  # Store in scope
834
838
  self.scope.set(var_name, instance)
839
+
840
+ # If global, also store in promoted_globals and global_scope
841
+ if is_global:
842
+ self._promoted_globals[var_name] = instance
843
+ self.global_scope.set(var_name, instance)
844
+
835
845
  return instance
836
846
 
837
847
  def _exec_instance_declaration(self, node: ASTNode) -> Any:
@@ -978,6 +988,14 @@ class CSSLRuntime:
978
988
  result = self._evaluate(inner.value)
979
989
  return result
980
990
 
991
+ # Handle typed declaration: global datastruct<int> data;
992
+ elif inner.type == 'typed_declaration':
993
+ # Add global modifier to the declaration
994
+ if isinstance(inner.value, dict):
995
+ inner.value['modifiers'] = inner.value.get('modifiers', []) + ['global']
996
+ result = self._exec_typed_declaration(inner)
997
+ return result
998
+
981
999
  # Fallback: execute normally
982
1000
  return self._execute_node(inner)
983
1001
 
@@ -1536,13 +1554,112 @@ class CSSLRuntime:
1536
1554
 
1537
1555
  # === DYNAMIC HELPERS ===
1538
1556
  elif filter_type == 'dynamic':
1539
- # dynamic::VarName=VALUE - Match if variable equals value
1540
- var_name = helper
1541
- var_value = self.scope.get(var_name)
1542
- if var_value == filter_val:
1543
- pass # Keep result
1557
+ if helper == 'content':
1558
+ # dynamic::content=VALUE - General content filter for any type
1559
+ # Filters elements where content equals VALUE
1560
+ if isinstance(result, (list, tuple)):
1561
+ # Filter list/tuple elements by content value
1562
+ result = [item for item in result if item == filter_val]
1563
+ elif isinstance(result, dict):
1564
+ # Filter dict by values matching filter_val
1565
+ result = {k: v for k, v in result.items() if v == filter_val}
1566
+ elif result == filter_val:
1567
+ pass # Keep result if it matches
1568
+ else:
1569
+ result = None
1570
+ elif helper == 'not':
1571
+ # dynamic::not=VALUE - Exclude elements equal to VALUE
1572
+ if isinstance(result, (list, tuple)):
1573
+ result = [item for item in result if item != filter_val]
1574
+ elif isinstance(result, dict):
1575
+ result = {k: v for k, v in result.items() if v != filter_val}
1576
+ elif result != filter_val:
1577
+ pass # Keep result if it doesn't match
1578
+ else:
1579
+ result = None
1580
+ elif helper == 'gt':
1581
+ # dynamic::gt=VALUE - Greater than
1582
+ if isinstance(result, (list, tuple)):
1583
+ result = [item for item in result if item > filter_val]
1584
+ elif result > filter_val:
1585
+ pass
1586
+ else:
1587
+ result = None
1588
+ elif helper == 'lt':
1589
+ # dynamic::lt=VALUE - Less than
1590
+ if isinstance(result, (list, tuple)):
1591
+ result = [item for item in result if item < filter_val]
1592
+ elif result < filter_val:
1593
+ pass
1594
+ else:
1595
+ result = None
1596
+ elif helper == 'gte':
1597
+ # dynamic::gte=VALUE - Greater than or equal
1598
+ if isinstance(result, (list, tuple)):
1599
+ result = [item for item in result if item >= filter_val]
1600
+ elif result >= filter_val:
1601
+ pass
1602
+ else:
1603
+ result = None
1604
+ elif helper == 'lte':
1605
+ # dynamic::lte=VALUE - Less than or equal
1606
+ if isinstance(result, (list, tuple)):
1607
+ result = [item for item in result if item <= filter_val]
1608
+ elif result <= filter_val:
1609
+ pass
1610
+ else:
1611
+ result = None
1612
+ elif helper == 'mod':
1613
+ # dynamic::mod=VALUE - Modulo filter (item % VALUE == 0)
1614
+ if isinstance(result, (list, tuple)):
1615
+ result = [item for item in result if isinstance(item, (int, float)) and item % filter_val == 0]
1616
+ elif isinstance(result, (int, float)) and result % filter_val == 0:
1617
+ pass
1618
+ else:
1619
+ result = None
1620
+ elif helper == 'range':
1621
+ # dynamic::range="min:max" - Filter values in range
1622
+ if isinstance(filter_val, str) and ':' in filter_val:
1623
+ parts = filter_val.split(':')
1624
+ min_val = int(parts[0]) if parts[0] else None
1625
+ max_val = int(parts[1]) if parts[1] else None
1626
+ if isinstance(result, (list, tuple)):
1627
+ def in_range(x):
1628
+ if min_val is not None and x < min_val:
1629
+ return False
1630
+ if max_val is not None and x > max_val:
1631
+ return False
1632
+ return True
1633
+ result = [item for item in result if in_range(item)]
1634
+ elif isinstance(result, (int, float)):
1635
+ if min_val is not None and result < min_val:
1636
+ result = None
1637
+ elif max_val is not None and result > max_val:
1638
+ result = None
1639
+ elif helper == 'even':
1640
+ # dynamic::even - Filter even numbers
1641
+ if isinstance(result, (list, tuple)):
1642
+ result = [item for item in result if isinstance(item, int) and item % 2 == 0]
1643
+ elif isinstance(result, int) and result % 2 == 0:
1644
+ pass
1645
+ else:
1646
+ result = None
1647
+ elif helper == 'odd':
1648
+ # dynamic::odd - Filter odd numbers
1649
+ if isinstance(result, (list, tuple)):
1650
+ result = [item for item in result if isinstance(item, int) and item % 2 != 0]
1651
+ elif isinstance(result, int) and result % 2 != 0:
1652
+ pass
1653
+ else:
1654
+ result = None
1544
1655
  else:
1545
- result = None
1656
+ # dynamic::VarName=VALUE - Match if variable equals value
1657
+ var_name = helper
1658
+ var_value = self.scope.get(var_name)
1659
+ if var_value == filter_val:
1660
+ pass # Keep result
1661
+ else:
1662
+ result = None
1546
1663
 
1547
1664
  # === SQL HELPERS ===
1548
1665
  elif filter_type == 'sql':
@@ -1756,9 +1873,14 @@ class CSSLRuntime:
1756
1873
  elif mode == 'move':
1757
1874
  # Move & remove from source
1758
1875
  final_value = source
1759
- # Clear the source
1760
- if isinstance(source_node, ASTNode) and source_node.type == 'identifier':
1761
- self.scope.set(source_node.value, None)
1876
+ # Clear the source - handle all node types
1877
+ if isinstance(source_node, ASTNode):
1878
+ if source_node.type == 'identifier':
1879
+ self.scope.set(source_node.value, None)
1880
+ elif source_node.type == 'module_ref':
1881
+ self._set_module_value(source_node.value, None)
1882
+ elif source_node.type == 'member_access':
1883
+ self._set_member(source_node, None)
1762
1884
  else:
1763
1885
  final_value = source
1764
1886
 
@@ -1830,9 +1952,36 @@ class CSSLRuntime:
1830
1952
  final_value = [current_value, source]
1831
1953
  elif mode == 'move':
1832
1954
  final_value = source
1833
- # Clear the source
1834
- if isinstance(source_node, ASTNode) and source_node.type == 'identifier':
1835
- self.scope.set(source_node.value, None)
1955
+ # Remove filtered elements from source (not clear entirely)
1956
+ if isinstance(source_node, ASTNode):
1957
+ if filter_info:
1958
+ # Get original source value
1959
+ original_source = self._evaluate(source_node)
1960
+ if isinstance(original_source, list) and isinstance(final_value, list):
1961
+ # Remove filtered items from original list
1962
+ remaining = [item for item in original_source if item not in final_value]
1963
+ if source_node.type == 'identifier':
1964
+ self.scope.set(source_node.value, remaining)
1965
+ elif source_node.type == 'module_ref':
1966
+ self._set_module_value(source_node.value, remaining)
1967
+ elif source_node.type == 'member_access':
1968
+ self._set_member(source_node, remaining)
1969
+ else:
1970
+ # Single value filter - set source to None
1971
+ if source_node.type == 'identifier':
1972
+ self.scope.set(source_node.value, None)
1973
+ elif source_node.type == 'module_ref':
1974
+ self._set_module_value(source_node.value, None)
1975
+ elif source_node.type == 'member_access':
1976
+ self._set_member(source_node, None)
1977
+ else:
1978
+ # No filter - clear entire source
1979
+ if source_node.type == 'identifier':
1980
+ self.scope.set(source_node.value, None)
1981
+ elif source_node.type == 'module_ref':
1982
+ self._set_module_value(source_node.value, None)
1983
+ elif source_node.type == 'member_access':
1984
+ self._set_member(source_node, None)
1836
1985
  else:
1837
1986
  final_value = source
1838
1987
 
@@ -2132,12 +2281,13 @@ class CSSLRuntime:
2132
2281
  return value
2133
2282
 
2134
2283
  if node.type == 'module_ref':
2135
- # Check modules first, then promoted globals, then scope
2136
- value = self.get_module(node.value)
2137
- if value is None:
2138
- value = self._promoted_globals.get(node.value)
2284
+ # User-defined globals have priority over SDK modules
2285
+ # Check promoted globals first, then global scope, then SDK modules
2286
+ value = self._promoted_globals.get(node.value)
2139
2287
  if value is None:
2140
2288
  value = self.global_scope.get(node.value)
2289
+ if value is None:
2290
+ value = self.get_module(node.value) # SDK modules as fallback
2141
2291
  return value
2142
2292
 
2143
2293
  if node.type == 'self_ref':
@@ -2221,12 +2371,28 @@ class CSSLRuntime:
2221
2371
  value_type = node.value.get('value_type') # For map<K, V>
2222
2372
  init_values = node.value.get('init_values') # For inline init: map<K,V>{...}
2223
2373
 
2374
+ # Helper to populate container with init values
2375
+ def _populate_container(container, init_vals):
2376
+ if init_vals and isinstance(init_vals, list):
2377
+ for val_node in init_vals:
2378
+ val = self._evaluate(val_node) if isinstance(val_node, ASTNode) else val_node
2379
+ if hasattr(container, 'push'):
2380
+ container.push(val)
2381
+ elif hasattr(container, 'add'):
2382
+ container.add(val)
2383
+ elif hasattr(container, 'append'):
2384
+ container.append(val)
2385
+ return container
2386
+
2224
2387
  if type_name == 'stack':
2225
- return Stack(element_type)
2388
+ s = Stack(element_type)
2389
+ return _populate_container(s, init_values)
2226
2390
  elif type_name == 'vector':
2227
- return Vector(element_type)
2391
+ v = Vector(element_type)
2392
+ return _populate_container(v, init_values)
2228
2393
  elif type_name == 'datastruct':
2229
- return DataStruct(element_type)
2394
+ d = DataStruct(element_type)
2395
+ return _populate_container(d, init_values)
2230
2396
  elif type_name == 'shuffled':
2231
2397
  return Shuffled(element_type)
2232
2398
  elif type_name == 'iterator':
@@ -2238,9 +2404,11 @@ class CSSLRuntime:
2238
2404
  elif type_name == 'openquote':
2239
2405
  return OpenQuote()
2240
2406
  elif type_name == 'array':
2241
- return Array(element_type)
2407
+ a = Array(element_type)
2408
+ return _populate_container(a, init_values)
2242
2409
  elif type_name == 'list':
2243
- return List(element_type)
2410
+ l = List(element_type)
2411
+ return _populate_container(l, init_values)
2244
2412
  elif type_name in ('dictionary', 'dict'):
2245
2413
  return Dictionary(element_type)
2246
2414
  elif type_name == 'map':
@@ -3027,12 +3195,20 @@ class CSSLRuntime:
3027
3195
  pass
3028
3196
 
3029
3197
  def _set_module_value(self, path: str, value: Any):
3030
- """Set a value on a module path"""
3198
+ """Set a value on a module path or promoted global"""
3031
3199
  parts = path.split('.')
3032
3200
  if len(parts) < 2:
3201
+ # Single name (no dots) - set in promoted_globals and global_scope
3202
+ self._promoted_globals[path] = value
3203
+ self.global_scope.set(path, value)
3033
3204
  return
3034
3205
 
3035
3206
  obj = self._modules.get(parts[0])
3207
+ # Also check promoted_globals for the base object
3208
+ if obj is None:
3209
+ obj = self._promoted_globals.get(parts[0])
3210
+ if obj is None:
3211
+ obj = self.global_scope.get(parts[0])
3036
3212
  if obj is None:
3037
3213
  return
3038
3214
 
@@ -64,6 +64,33 @@ class DataStruct(list):
64
64
  return target_type(self[0])
65
65
  return None
66
66
 
67
+ def length(self) -> int:
68
+ """Return datastruct length"""
69
+ return len(self)
70
+
71
+ def size(self) -> int:
72
+ """Return datastruct size (alias for length)"""
73
+ return len(self)
74
+
75
+ def push(self, item: Any) -> 'DataStruct':
76
+ """Push item to datastruct (alias for add)"""
77
+ self.append(item)
78
+ return self
79
+
80
+ def isEmpty(self) -> bool:
81
+ """Check if datastruct is empty"""
82
+ return len(self) == 0
83
+
84
+ def contains(self, item: Any) -> bool:
85
+ """Check if datastruct contains item"""
86
+ return item in self
87
+
88
+ def at(self, index: int) -> Any:
89
+ """Get item at index (safe access)"""
90
+ if 0 <= index < len(self):
91
+ return self[index]
92
+ return None
93
+
67
94
  def begin(self) -> int:
68
95
  """Return iterator to beginning (C++ style)"""
69
96
  return 0
@@ -99,6 +126,16 @@ class Stack(list):
99
126
  self.append(item)
100
127
  return self
101
128
 
129
+ def pop(self) -> Any:
130
+ """Pop and return top element from stack"""
131
+ if len(self) == 0:
132
+ return None
133
+ return super().pop()
134
+
135
+ def pop_back(self) -> Any:
136
+ """Pop and return top element (alias for pop)"""
137
+ return self.pop()
138
+
102
139
  def peek(self) -> Any:
103
140
  """View top item without removing"""
104
141
  return self[-1] if self else None
@@ -701,6 +738,39 @@ class List(list):
701
738
  self.extend([value] * count)
702
739
  return self
703
740
 
741
+ def map(self, func: Callable[[Any], Any]) -> 'List':
742
+ """Apply function to all elements"""
743
+ result = List(self._element_type)
744
+ result.extend(func(item) for item in self)
745
+ return result
746
+
747
+ def filter(self, predicate: Callable[[Any], bool]) -> 'List':
748
+ """Filter elements by predicate"""
749
+ result = List(self._element_type)
750
+ result.extend(item for item in self if predicate(item))
751
+ return result
752
+
753
+ def forEach(self, func: Callable[[Any], None]) -> 'List':
754
+ """Execute function for each element"""
755
+ for item in self:
756
+ func(item)
757
+ return self
758
+
759
+ def reduce(self, func: Callable[[Any, Any], Any], initial: Any = None) -> Any:
760
+ """Reduce list to single value"""
761
+ from functools import reduce as py_reduce
762
+ if initial is None:
763
+ return py_reduce(func, self)
764
+ return py_reduce(func, self, initial)
765
+
766
+ def every(self, predicate: Callable[[Any], bool]) -> bool:
767
+ """Check if all elements match predicate"""
768
+ return all(predicate(item) for item in self)
769
+
770
+ def some(self, predicate: Callable[[Any], bool]) -> bool:
771
+ """Check if any element matches predicate"""
772
+ return any(predicate(item) for item in self)
773
+
704
774
  def begin(self) -> int:
705
775
  """Return iterator to beginning"""
706
776
  return 0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: IncludeCPP
3
- Version: 3.7.20
3
+ Version: 3.7.22
4
4
  Summary: Professional C++ Python bindings with type-generic templates, pystubs and native threading
5
5
  Home-page: https://github.com/liliassg/IncludeCPP
6
6
  Author: Lilias Hatterscheidt
@@ -1,9 +1,9 @@
1
- includecpp/__init__.py,sha256=4Ymntg7zK4sO2Z-sJmMHLXLI0Dqe1DbKESuvJYSZgDg,1673
1
+ includecpp/__init__.py,sha256=I8UAmvZc1D4Tu6GT2QK0sNoj4q5i2dhrR0Isyb0tJRA,1673
2
2
  includecpp/__init__.pyi,sha256=uSDYlbqd2TinmrdepmE_zvN25jd3Co2cgyPzXgDpopM,7193
3
3
  includecpp/__main__.py,sha256=d6QK0PkvUe1ENofpmHRAg3bwNbZr8PiRscfI3-WRfVg,72
4
4
  includecpp/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  includecpp/cli/__init__.py,sha256=Yda-4a5QJb_tKu35YQNfc5lu-LewTsM5abqNNkzS47M,113
6
- includecpp/cli/commands.py,sha256=AeHirETVkzNqNcqh5RVO0ABPz_6gfuV2EpHcWK9BuDY,349032
6
+ includecpp/cli/commands.py,sha256=HDoRuPEPTzxZQcR4rF45GrRVtcw3zDj6cGiwLCZB44Y,349597
7
7
  includecpp/cli/config_parser.py,sha256=KveeYUg2TA9sC5hKVzYYfgdNm2WfLG5y7_yxgBWn9yM,4886
8
8
  includecpp/core/__init__.py,sha256=L1bT6oikTjdto-6Px7DpjePtM07ymo3Bnov1saZzsGg,390
9
9
  includecpp/core/ai_integration.py,sha256=PW6yFDqdXjfchpfKTKg59AOLhLry9kqJEGf_65BztrY,87603
@@ -21,14 +21,14 @@ includecpp/core/project_ui.py,sha256=la2EQZKmUkJGuJxnbs09hH1ZhBh9bfndo6okzZsk2dQ
21
21
  includecpp/core/settings_ui.py,sha256=B2SlwgdplF2KiBk5UYf2l8Jjifjd0F-FmBP0DPsVCEQ,11798
22
22
  includecpp/core/cssl/CSSL_DOCUMENTATION.md,sha256=47sUPO-FMq_8_CrJBZFoFBgSO3gSi5zoB1Xp7oeifho,40773
23
23
  includecpp/core/cssl/__init__.py,sha256=scDXRBNK2L6A8qmlpNyaqQj6BFcSfPInBlucdeNfMF0,1975
24
- includecpp/core/cssl/cssl_builtins.py,sha256=6L2C_74mlVnd5C27z9LwmD5Z2jbT4wXp_QNb34cA004,89578
24
+ includecpp/core/cssl/cssl_builtins.py,sha256=r-FX4WQeKxerkepqodIiwhtL_kxxa4PJym_WyWIwA_s,92290
25
25
  includecpp/core/cssl/cssl_builtins.pyi,sha256=3ai2V4LyhzPBhAKjRRf0rLVu_bg9ECmTfTkdFKM64iA,127430
26
26
  includecpp/core/cssl/cssl_events.py,sha256=nupIcXW_Vjdud7zCU6hdwkQRQ0MujlPM7Tk2u7eDAiY,21013
27
27
  includecpp/core/cssl/cssl_modules.py,sha256=cUg0-zdymMnWWTsA_BUrW5dx4R04dHpKcUhm-Wfiwwo,103006
28
- includecpp/core/cssl/cssl_parser.py,sha256=YLQUnuKwY37d1LtrJ2UMysgpAXVgIvcRQO7gUFUONts,113476
29
- includecpp/core/cssl/cssl_runtime.py,sha256=6wtifsRurFRm62KrdnTpzNdofl5vSOfaHM6KPXzhJVE,142036
28
+ includecpp/core/cssl/cssl_parser.py,sha256=G9DxPLcmR7rhQvrxskp4Y8l8nXQy0tymkUVpsWWS6VM,116027
29
+ includecpp/core/cssl/cssl_runtime.py,sha256=1z_TecgGmMjiO5RiI_eQeebToyFKZvdpbFU61b6XRUQ,152125
30
30
  includecpp/core/cssl/cssl_syntax.py,sha256=bgo3NFehoPTQa5dqwNd_CstkVGVCNYAXbGYUcu5BEN0,16982
31
- includecpp/core/cssl/cssl_types.py,sha256=ebgZrrddhmTRK8vQ3dNWVH15Z4rMqEx1sSmozhnJyQA,48292
31
+ includecpp/core/cssl/cssl_types.py,sha256=gVjtfxk0Uzfj-H7_LD79oqspFMYDf79ZrRrlZk8eAEs,50647
32
32
  includecpp/generator/__init__.py,sha256=Rsy41bwimaEloD3gDRR_znPfIJzIsCFuWZgCTJBLJlc,62
33
33
  includecpp/generator/parser.cpp,sha256=hbhHdtFH65rzp6prnARN9pNFF_ssr0NseVVcxq0fJh4,76833
34
34
  includecpp/generator/parser.h,sha256=EDm0b-pEesIIIQQ2PvH5h2qwlqJU9BH8SiMV7MWbsTo,11073
@@ -43,9 +43,9 @@ includecpp/vscode/cssl/images/cssl.png,sha256=BxAGsnfS0ZzzCvqV6Zb1OAJAZpDUoXlR86
43
43
  includecpp/vscode/cssl/images/cssl_pl.png,sha256=z4WMk7g6YCTbUUbSFk343BO6yi_OmNEVYkRenWGydwM,799
44
44
  includecpp/vscode/cssl/snippets/cssl.snippets.json,sha256=l4SCEPR3CsPxA8HIVLKYY__I979TfKzYWtH1KYIsboo,33062
45
45
  includecpp/vscode/cssl/syntaxes/cssl.tmLanguage.json,sha256=XKRLBOHlCqDDnGPvmNHDQPsIMR1UD9PBaJIlgZOiPqM,21173
46
- includecpp-3.7.20.dist-info/licenses/LICENSE,sha256=fWCsGGsiWZir0UzDd20Hh-3wtRyk1zqUntvtVuAWhvc,1093
47
- includecpp-3.7.20.dist-info/METADATA,sha256=K63lr_YXZIRgYK-UUGPkwnRp4f-9JqvyJZtpibEjKFI,32122
48
- includecpp-3.7.20.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
49
- includecpp-3.7.20.dist-info/entry_points.txt,sha256=6A5Mif9gi0139Bf03W5plAb3wnAgbNaEVe1HJoGE-2o,59
50
- includecpp-3.7.20.dist-info/top_level.txt,sha256=RFUaR1KG-M6mCYwP6w4ydP5Cgc8yNbP78jxGAvyjMa8,11
51
- includecpp-3.7.20.dist-info/RECORD,,
46
+ includecpp-3.7.22.dist-info/licenses/LICENSE,sha256=fWCsGGsiWZir0UzDd20Hh-3wtRyk1zqUntvtVuAWhvc,1093
47
+ includecpp-3.7.22.dist-info/METADATA,sha256=XgO09qXzPsH5vKUtuvQ8ptcv9plaocylViuM4c4V2p0,32122
48
+ includecpp-3.7.22.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
49
+ includecpp-3.7.22.dist-info/entry_points.txt,sha256=6A5Mif9gi0139Bf03W5plAb3wnAgbNaEVe1HJoGE-2o,59
50
+ includecpp-3.7.22.dist-info/top_level.txt,sha256=RFUaR1KG-M6mCYwP6w4ydP5Cgc8yNbP78jxGAvyjMa8,11
51
+ includecpp-3.7.22.dist-info/RECORD,,