2929 AnonymousName ,
3030 Array ,
3131 ClassDecl ,
32+ Concept ,
3233 DecoratedType ,
3334 EnumDecl ,
3435 Field ,
@@ -381,6 +382,9 @@ def on_namespace_alias(
381382 # TODO: add to some sort of resolver?
382383 pass
383384
385+ def on_concept (self , state : AWNonClassBlockState , concept : Concept ) -> None :
386+ pass
387+
384388 def on_forward_decl (self , state : AWState , fdecl : ForwardDecl ) -> None :
385389 # TODO: add to some sort of resolver?
386390 pass
@@ -447,6 +451,16 @@ def on_using_declaration(self, state: AWState, using: UsingDecl) -> None:
447451
448452 if using .access is None :
449453 self .hctx .using_declarations .append (using .typename )
454+ elif isinstance (state , ClassBlockState ):
455+ # A using declaration might bring in a colliding name for a function,
456+ # so mark it as overloaded
457+ lseg = using .typename .segments [- 1 ]
458+ if isinstance (lseg , NameSpecifier ):
459+ cdata = state .user_data
460+ name = lseg .name
461+ self .gendata .add_using_decl (
462+ name , cdata .cls_key , cdata .data , state .access == "private"
463+ )
450464
451465 #
452466 # Enums
@@ -566,7 +580,11 @@ def on_class_start(self, state: AWClassBlockState) -> typing.Optional[bool]:
566580 ):
567581 return False
568582
569- cls_key , cls_name , cls_namespace , parent_ctx = self ._process_class_name (state )
583+ cls_name_result = self ._process_class_name (state )
584+ if cls_name_result is None :
585+ return False
586+
587+ cls_key , cls_name , cls_namespace , parent_ctx = cls_name_result
570588 class_data = self .gendata .get_class_data (cls_key )
571589
572590 # Ignore explicitly ignored classes
@@ -647,6 +665,7 @@ def on_class_start(self, state: AWClassBlockState) -> typing.Optional[bool]:
647665 template_parameter_list = ", " .join (template_params )
648666
649667 template_data = ClassTemplateData (
668+ argument_list = template_argument_list ,
650669 parameter_list = template_parameter_list ,
651670 inline_code = class_data .template_inline_code ,
652671 )
@@ -746,23 +765,24 @@ def on_class_start(self, state: AWClassBlockState) -> typing.Optional[bool]:
746765
747766 def _process_class_name (
748767 self , state : AWClassBlockState
749- ) -> typing .Tuple [str , str , str , typing .Optional [ClassContext ]]:
768+ ) -> typing .Optional [ typing . Tuple [str , str , str , typing .Optional [ClassContext ] ]]:
750769 class_decl = state .class_decl
751770 segments = class_decl .typename .segments
752771 assert len (segments ) > 0
753772
754- name_segment = segments [- 1 ]
755- if not isinstance (name_segment , NameSpecifier ):
756- raise ValueError (f"not sure how to handle '{ class_decl .typename } '" )
757-
758- cls_name = name_segment .name
773+ segment_names : typing .List [str ] = []
774+ for segment in segments :
775+ if not isinstance (segment , NameSpecifier ):
776+ raise ValueError (
777+ f"not sure how to handle '{ class_decl .typename .format ()} '"
778+ )
779+ # ignore specializations for now
780+ if segment .specialization is not None :
781+ return None
782+ segment_names .append (segment .name )
759783
760- # for now, don't support these?
761- other_segments = segments [:- 1 ]
762- if other_segments :
763- raise ValueError (
764- f"not sure what to do with compound name '{ class_decl .typename } '"
765- )
784+ cls_name = segment_names [- 1 ]
785+ extra_segments = "::" .join (segment_names [:- 1 ])
766786
767787 parent_ctx : typing .Optional [ClassContext ] = None
768788
@@ -772,13 +792,18 @@ def _process_class_name(
772792 # easy case -- namespace is the next user_data up
773793 cls_key = cls_name
774794 cls_namespace = typing .cast (str , parent .user_data )
795+ if extra_segments :
796+ cls_namespace = f"{ cls_namespace } ::{ extra_segments } "
775797 else :
776798 # Use things the parent already computed
777799 cdata = typing .cast (ClassStateData , parent .user_data )
778800 # parent: AWClassBlockState = state.parent
779801 parent_ctx = cdata .ctx
780802 # the parent context already computed namespace, so use that
781- cls_key = f"{ cdata .cls_key } ::{ cls_name } "
803+ if extra_segments :
804+ cls_key = f"{ cdata .cls_key } ::{ extra_segments } ::{ cls_name } "
805+ else :
806+ cls_key = f"{ cdata .cls_key } ::{ cls_name } "
782807 cls_namespace = parent_ctx .namespace
783808
784809 return cls_key , cls_name , cls_namespace , parent_ctx
@@ -1028,6 +1053,23 @@ def _on_class_method(
10281053 self .hctx .need_operators_h = True
10291054 if method_data .no_release_gil is None :
10301055 fctx .release_gil = False
1056+
1057+ # Use cpp_code to setup the operator
1058+ if fctx .cpp_code is None :
1059+ if len (method .parameters ) == 0 :
1060+ fctx .cpp_code = f"{ operator } py::self"
1061+ else :
1062+ ptype , _ , _ , _ = _count_and_unwrap (method .parameters [0 ].type )
1063+ if (
1064+ isinstance (ptype , Type )
1065+ and isinstance (ptype .typename .segments [- 1 ], NameSpecifier )
1066+ and ptype .typename .segments [- 1 ].name == cdata .ctx .cpp_name
1067+ ):
1068+ # don't try to predict the type, use py::self instead
1069+ fctx .cpp_code = f"py::self { operator } py::self"
1070+ else :
1071+ fctx .cpp_code = f"py::self { operator } { fctx .all_params [0 ].cpp_type_no_const } ()"
1072+
10311073 if method .const :
10321074 fctx .const = True
10331075 if method .static :
0 commit comments