2014-04-08 3 views
0

"상자 형"(인터프리터 용) 구현에서는 원래 하위 패키지에 벡터가 있고 System.Address에서 Vector_Ptr로 변환 할 때 System.Access_To_Address_Conversions를 사용하여 주기적 종속성으로 인해 극복 할 수없는 문제를 피하십시오. (적어도, 모든 사람에게 제한된 사용은 나를 위해 속임수를 쓰지 않았습니다.) 그것은 효과가 있었지만 불쾌한 해킹처럼 보였습니다. 그래서 컨테이너 유형을 주 패키지 Types.Boxed에 넣기로 결정했습니다. 이제 GNAT는 불완전한 타입의 보이는 부분에 "벡터"라는 라인 12 '에 정의 된 선언을하지 않습니다.상호 의존형 선언 및 Ada.Containers

이 문제를 해결할 방법이 있습니까? 아니면 내가 불쾌한 해킹으로 돌아 가야 하나? 플래그 GNAT 4.6을 사용하여

에이다 2005

는 -gnat05

with Interfaces; use Interfaces; 
with Ada.Strings.Wide_Unbounded; use Ada.Strings.Wide_Unbounded; 
with Ada.Containers.Vectors; 
with Green_Tasks; use Green_Tasks; 

package Types.Boxed is 

    type Type_T is (T_Null, T_Unsigned_64, T_String, T_Boolean, 
        T_Green_Task, T_Vector); 

    type String_Ptr is access all Unbounded_Wide_String; 
    type Vector; 
    type Vector_Ptr is access all Vector; 

    type Item (IType : Type_T := T_Null) is record 
     case IType is 
     when T_Null  => null; 
     when T_Unsigned_64 => Value_Unsigned_64 : Unsigned_64; 
     when T_String  => Value_String  : String_Ptr; 
     when T_Boolean  => Value_Boolean  : Boolean; 
     when T_Green_Task => Value_Green_Task : Green_Task_Ptr; 
     when T_Vector  => Value_Vector  : Vector_Ptr; 
     end case; 
    end record; 

    procedure Free (Datum : in out Item); 
    procedure Box (Datum : out Item; Value : in Unsigned_64); 
    function Unbox (Datum : Item) return Unsigned_64; 
    procedure Box (Datum : out Item; Value : String_Ptr); 
    function Unbox (Datum : Item) return String_Ptr; 
    procedure Box (Datum : out Item; Value : in Boolean); 
    function Unbox (Datum : Item) return Boolean; 
    procedure Box (Datum : out Item; Value : in Green_Task_Ptr); 
    function Unbox (Datum : Item) return Green_Task_Ptr; 
    function Get_Boxed_Type (Datum : Item) return Type_T; 

    -- vectors 
    package Item_Vectors is new Ada.Containers.Vectors 
    (Index_Type => Natural, 
     Element_Type => Item 
    ); 
    use Item_Vectors; 


    function Vector_New (Size_Hint : Positive) return Item; 
    function Unbox (Datum : Item) return Vector_Ptr; 
    procedure Vector_Free (V : in out Vector_Ptr); 
    function Vector_Copy (V : Vector_Ptr) return Item; 

    pragma Inline (Box); 
    pragma Inline (Unbox); 
    pragma Pure_Function (Unbox); 
    pragma Pure_Function (Get_Boxed_Type); 


end Types.Boxed; 

답변

3

OK, 난 당신이 Item_Vectors을 인스턴스화 Item_VectorsVector 유형이 이전에 쓴 불완전 Vector 완료 될 것이라고, use Item_Vectors을 말했을 때 당신이 생각한다고 가정합니다.

그렇지 않습니다. use P이라고 말하면 P에 정의 된 모든 이름이 바로 표시되므로 PT 유형을 선언하는 경우 P.T 대신 T을 말할 수 있습니다. 그러나 기호는 여전히 P에 속합니다. 그들은 use을 포함하는 패키지의 "일부"가되지 않습니다. 예를 들어, use Item_Vectors;Item_Vectors.Empty_Cursor 대신 Empty_Cursor이라고 말할 수 있음을 의미합니다. 하지만 이 아닌Types.Boxed.Empty_Cursor이됩니다. 이름은 여전히 ​​Item_Vectors에 속합니다.

은 이것이 의미하는 것은 당신이 Types.Boxed에서 불완전 Vector 유형이있을 때,Types.Boxed에 완료 있을 필요가 있다는 것입니다. Vector 유형이 Item_Vectors 인 경우 유형 완성이되지 않으며 use이 도움이되지 않습니다.

Ada는 "유형 바꾸기"또는 subtype이있는 유형을 완성하도록 허용하지 않습니다. 내가 생각할 수있는 최선의 선택은 Vector에 대한 상속이가 Item_Vector에서 모든 작업을 유발한다는

type Vector is new Item_Vectors.Vector with null record; 

주입니다. 이렇게하면 효과가있을 것입니다. 그러나 예기치 않은 문제가있을 수 있습니다. 그러나 나는 더 나은 해결책을 생각할 수 없다.

편집 : 사이먼은 좋은 해결책이있는 것처럼 보입니다.

+0

컨테이너를 확장하는 문제는 컨테이너 유형 (Vector has 7)을 반환하는 함수의 수이며 따라서 오버라이드해야합니다. –

+1

@SimonWright 아니요, 2005 년 Ada에서 유형 확장이 _ 내선 확장 인 경우 함수를 재정의 할 필요가 없습니다. – ajb

+0

O 예, 이제는 그 라인에서 * my * 시도의 요점은 확장이 추가 내용을 가지고 있다는 것입니다. 죄송합니다. –

1

나는이 주위에 연주하고 나는 그것이 요소 유형 Item_PtrItem_Vectors하여 컴파일 얻을 수있는 것을 발견 : (

type Item (<>); 
type Item_Ptr is access all Item; 

package Item_Vectors is new Ada.Containers.Vectors 
(Index_Type => Natural, 
    Element_Type => Item_Ptr 
); 
subtype Vector is Item_Vectors.Vector; 
type Vector_Ptr is access all Vector; 

type Item (IType : Type_T := T_Null) is record 
    case IType is 
     when T_Null  => null; 
     when T_Unsigned_64 => Value_Unsigned_64 : Unsigned_64; 
     when T_String  => Value_String  : String_Ptr; 
     when T_Boolean  => Value_Boolean  : Boolean; 
     when T_Vector  => Value_Vector  : Vector_Ptr; 
    end case; 
end record; 

Green_Tasks이 삭제되었으므로 문제가되지 않을 것으로 예상됩니다.)

ARM 3.10.1(3)에서 불완전한 선언이 개인 부분에있는 경우에만 전체 선언을 본문으로 연기 할 수 있다는 것을 알았 으면합니다.