Ada_Ru форум

Обсуждение языка Ада

Как лучше объявлять умные указатели?

Оставить новое сообщение

Сообщения

Иван Леваше
Как лучше объявлять умные указатели?
2013-01-30 01:44:56
Здравствуйте!

В Delphi мне очень нравится то, как устроены интерфейсы на практическом 
уровне. На языковом уровне я не вижу необходимости делать подсчёт ссылок 
для ссылок на интерфейсы и не делать его для ссылок на классы.

Интерфейсы могут объявляться вперёд, так что методы интерфейса без 
проблем принимают на вход и на выход как аналогичные интерфейсы, так и 
другие, в том числе объявленные вперёд.

IXMLDocument в обращении гораздо легче, чем DOM в XMLAda, и такие лёгкие 
в обращении интерфейсы относительно несложно делать в Delphi. Жаль, что 
Embarcadero и разработчики Free Pascal постоянно динамят любителей 
счётчиков ссылок.


В языке Ада всё довольно просто, пока мы оперируем независимыми умными 
указателями. При попытке написать generic (Gnatcoll.Refcount не 
подходит, так как инкапсулированный тип private, а мне для SQL_Database, 
task и прочего надо limited private) всплывают такие подробности:

Непонятно, как лучше объявлять типы, которые будут сидеть в динамической 
памяти, и как объявлять умные указатели для них. На первый взгляд 
кажется, что нужно делать параллельные иерархии: иерархия умных 
указателей дублирует иерархию типов в динамической памяти. Проблема при 
этом в том, что, так как в языке Ада нет неявного приведения типов и нет 
перегрузки явного приведения, тип умного указателя начинает тащиться 
вслед за умным указателем. То есть, если указатель на объект сидит в 
умном указателе, и этот умный указатель передаётся в чей–то метод с 
формальным аргументом Root_Pointer'Class, но ожидается, что в нём сидит 
указатель на Derived_Class, попытка привести Root_Pointer'Class к 
Derived_Pointer может быть удачной или неудачной в зависимости от того, 
каким был тип самого умного указателя у аргумента. И это мне очень не 
нравится. Обычное наследование подходит для типов, на которые ссылаются, 
но не для самих умных указателей.

В стандарте Ada 2012 появляется аспект Implicit_Dereference, но при этом 
сделано всё возможное, чтобы можно было удобно присвоить элемент в 
контейнере, но чтобы это не решало ни одну другую проблему.

Механизм subtype больше, чем наследование подходит для иерархии умных 
указателей. Если у нас есть

type Root_Pointer (Data : access Root_Class'Class := null) is private
with Implicit_Dereference => Data;

то напрашивается

subtype Derived_Pointer is Root_Pointer (Derived_Class'Class);

или хотя бы

subtype Derived_Pointer (Data : access Derived_Class'Class := null) is 
Root_Pointer (Data);

Это было бы особенно хорошо тем, что не нужно дублировать методы в 
инкапсулированном типе и в умном указателе, Implicit_Dereference сделает 
это за нас. То, как устроена подтипизация в языке Ада, мне кажется, как 
раз бы подошло для умных указателей, если бы это было возможно. Проблемы 
при таком использовании начнутся прямо с попытки объявить access 
discriminant with default. Без default умные указатели нахрен бы не 
сдались, они будут unconstrained, их никуда положить толком нельзя 
будет. Скажем, Ada.Task_Attributes требует type Attribute is private; 
без всяких там (<>) и без limited.

Ещё одна наверняка решаемая проблема при цикличных зависимостях. limited 
with позволяет использовать только указатели на чужие типы, а умный 
указатель — не указатель. При попытке написать generic приходится 
предусматривать это, но я пока детально не вдавался ещё.

Третья или какая по счёту идея в том, чтобы сделать умные указатели 
абсолютно не связанными (без общего корня), по приводимыми через, 
например, унарный "+" или function Downcast, function Upcast, function 
To_Derived_Pointer или что–то типа того. Каждый, кто реализует класс, 
предоставляет generic package, объявляющий независимый умный указатель с 
объявлениями всех методов, чтобы каждый, кто реализует потомков, мог, 
используя этот generic, объявить свой generic, в котором дополнить 
методы указателя базового класса своими методами. И ещё надо что–то 
придумать с приведениями типов. Пока не знаю, насколько хорошо GNAT 
будет справляться с таким нагромождением generics.

У проектов типа GNATCOM eсть преимущество в том, что бреши в системе 
типов (кажется, то, что мне нужно, называется ковариантность и 
контравариантность при параметрическом полиморфизме) можно заливать 
генерацией кода.

В Аda 2012 появляется subtype predicates. Static_Predicate можно, 
похоже, использовать для проверки на принадлежность к подклассу. 
Красивых селекторов для subtype при этом не получится. Даже, если писать 
.Data., Data будет access Root_Class'Class, его нужно будет приводить к 
access Derived_Class'Class и только тогда вызывать метод. Плохо, что 
селекторы не могут быть у подтипов иначе, чем через Implicit_Dereference.

type is new для не-tagged типов oтлично бы подошли в сочетании с subtype 
predicates, если бы только у не–tagged типов были селекторы. Или если бы 
для них было доступно горизонтальное наследование (изменение вида без 
изменения типа), то есть, type is new с дополнительными примитивными 
операциями, но без with record, чтоб любой Root_Pointer мoжно было 
приводить к Derived_Pointer при выполнении ограничений подтипа типа 
Derived_Pointer.

Пишите, если я упустил какую–то простую возможность.

С уважением,
Левашев Иван

-- 
If you want to get to the top, you have to start at the bottom
kazakov1961
Re: [ada_ru] Как лучше объявлять умные указатели?
2013-01-30 09:15:43
On Wed, 30 Jan 2013 08:44:56 +0700, you wrote:

> В языке Ада всё довольно просто, пока мы оперируем независимыми умными 
> указателями. При попытке написать generic (Gnatcoll.Refcount не 
> подходит, так как инкапсулированный тип private, а мне для SQL Database, 
> task и прочего надо limited private) всплывают такие подробности:

Тут limited private:

http://www.dmitry-kazakov.de/ada/components.htm#Objects etc

> Непонятно, как лучше объявлять типы, которые будут сидеть в динамической 
> памяти, и как объявлять умные указатели для них. На первый взгляд 
> кажется, что нужно делать параллельные иерархии: иерархия умных 
> указателей дублирует иерархию типов в динамической памяти.

В Аде 2005 есть interfaces, что частично решает проблему через делегацию:

Интерфейс

   type SQL Interface is limited interface;
   procedure Foo (X : in out SQL Interface) is abstract; -- Operation

Реализация

   with Object.Handle;

   type SQL Object is new Object.Entity and SQL Interface with private;
   type SQL Object Ptr is access SQL Object'Class;
   procedure Foo (X : in out SQL Object); -- Implement it here

Указатели

   with Object.Handle;

   package SQL Object Handles is
      new Object.Handle (SQL Object, SQL Object Ptr);

   type SQL Object Handle is
      new SQL Object Handles.Handle and SQL Interface with null record;
   procedure Foo (X : in out SQL Object Handle); -- Delegate

   procedure Foo (X : in out SQL Object Handle) is
   begin
       X.Ptr.Foo; -- Delegation
   end Foo;

Проблема в том, что для каждой операции надо писать делегатор. К сожалению,
компилятор не генерирует их автоматически, как должен бы.

> В стандарте Ada 2012 появляется аспект Implicit Dereference, но при этом 
> сделано всё возможное, чтобы можно было удобно присвоить элемент в 
> контейнере, но чтобы это не решало ни одну другую проблему.
> 
> Механизм subtype больше, чем наследование подходит для иерархии умных 
> указателей. Если у нас есть
> 
> type Root Pointer (Data : access Root Class'Class := null) is private
> with Implicit Dereference => Data;
> 
> то напрашивается
> 
> subtype Derived Pointer is Root Pointer (Derived Class'Class);

Это наверное уже возможно через предикаты в 2012, но не решает проблему
параллельный иерархий. Она гораздо сложнее, чем кажется.

Я предлагал рассмотреть механизм распространения ограничений на компоненты
типов, но интереса нет. В нашем случае механизм должен ограничивать T'Class
в конкретный тип.

Для параллельный иерархий требуется еще наследование интерфейсов (без
реализации), наследование от конкретных типов (без факторизации
интерфейса), автоматическая делегация (реализация методов через генерацию
делегаторов). Первые два эквивалентны ad-hoc подтипам. Т.к. в конечном
итоге, требуется чтобы указатель был подтипом указуемого объекта.

> Ещё одна наверняка решаемая проблема при цикличных зависимостях. limited 
> with позволяет использовать только указатели на чужие типы, а умный 
> указатель — не указатель. При попытке написать generic приходится 
> предусматривать это, но я пока детально не вдавался ещё.

В примере который я привел, реализация может быть спрятана в приватный
пакет.

> Третья или какая по счёту идея в том, чтобы сделать умные указатели 
> абсолютно не связанными (без общего корня), по приводимыми через, 
> например, унарный "+" или function Downcast, function Upcast, function 
> To Derived Pointer или что–то типа того. Каждый, кто реализует класс, 
> предоставляет generic package, объявляющий независимый умный указатель с 
> объявлениями всех методов, чтобы каждый, кто реализует потомков, мог, 
> используя этот generic, объявить свой generic, в котором дополнить 
> методы указателя базового класса своими методами. И ещё надо что–то 
> придумать с приведениями типов. Пока не знаю, насколько хорошо GNAT 
> будет справляться с таким нагромождением generics.

Будет. Эта схема действительно реализована в реальном проекте.

GNAT-у требуется более 2Гб памяти для его компиляции! Так что под Win32 он
вылетает. Но под Win64 справляется.

Конечно, сотни (может и тысяча, не считал) генериков - удовольствие ниже
среднего.

> В Аda 2012 появляется subtype predicates. Static Predicate можно, 
> похоже, использовать для проверки на принадлежность к подклассу. 
> Красивых селекторов для subtype при этом не получится. Даже, если писать 
> .Data., Data будет access Root Class'Class, его нужно будет приводить к 
> access Derived Class'Class и только тогда вызывать метод. Плохо, что 
> селекторы не могут быть у подтипов иначе, чем через Implicit Dereference.
> 
> type is new для не-tagged типов oтлично бы подошли в сочетании с subtype 
> predicates, если бы только у не–tagged типов были селекторы.

Да, это была одна из самых тяжелых ошибок дизайна ada.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
Vasiliy Fofanov
Re: [ada_ru] Как лучше объявлять умные указатели?
2013-01-30 09:42:13
> Я предлагал рассмотреть механизм распространения ограничений на компоненты
> типов, но интереса нет. В нашем случае механизм должен ограничивать T'Class
> в конкретный тип.

Дмитрий, не развернете ли здесь подробнее? Что именно вы предлагаете? Если это здесь уже
обсуждалось возможно я пропустил.

С уважением,
ВФ
kazakov1961
Re: [ada_ru] Как лучше объявлять умные указатели?
2013-01-30 10:32:42
On Wed, 30 Jan 2013 10:42:13 +0100, you wrote:

>> Я предлагал рассмотреть механизм распространения ограничений на компоненты
>> типов, но интереса нет. В нашем случае механизм должен ограничивать T'Class
>> в конкретный тип.
> 
> Дмитрий, не развернете ли здесь подробнее? Что именно вы предлагаете? Если
> это здесь уже обсуждалось возможно я пропустил.

[<rant on> Конкретно, хочу обсуждения развития системы типов Ады.
Ограничения - один из ее механизмов. Предложения писать бесполезно, если
нет интереса. А его явно нет. Не хочу заплаток типа аспектов, динамических
предикатов и т.п. разрушающих единство языка. Т.к. вопрос очень сложен, его
нельзя решить в рамках AI. AI - хороши только для заплаток, и только
заплатки проходят через этот механизм. Нужна программа переработки языка и
лидеры типа Ichbiah и Taft-a. <rant off>]

Касательно ограничений, желательно

1. Трактовка T как ограниченного T'Class. Разумеется через дискриминант
типа Tag.

2. Возможность распространения ограничения на компоненты типа. Например:

   type T Class Array (What : Tag) is
      array (Positive range <>) of T'Class (What);

   type S is new T with ...;
   subtype S Array is T Class Array (S'Tag); -- Ограничили элементы до S

3. Разумеется, границы массивов тоже должны быть дискриминантами.

4. Должен присутствовать механизм удаления статического ограничения из
представления, как это делается в случае границ массивов.

В частности, 1+4 дает классы для всех типов. Например, Boolean'Class
содержит тэг, в Boolean он удален т.к. статически известен.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
Иван Леваше
Re: Как лучше объявлять умные указатели?
2013-01-30 12:57:30
30.01.2013 16:15, Dmitry A. Kazakov пишет:

> Конечно, сотни (может и тысяча, не считал) генериков - удовольствие ниже
> среднего.

Короче, somFree может пригодиться там, где его не ждали.

>> type is new для не-tagged типов oтлично бы подошли в сочетании с subtype
>> predicates, если бы только у не–tagged типов были селекторы.
>
> Да, это была одна из самых тяжелых ошибок дизайна ada.

Попытался добавить примитивную операцию внутри generic, который не знает 
о том, что его private параметризующий тип tagged. Получаю ошибку 
подстановки :(

test_hi.adb:31:04: instantiation error at line 16
test_hi.adb:31:04: type derived from tagged type must have extension
test_hi.adb:39:41: downward conversion of tagged objects not allowed
gnatmake: "test_hi.adb" compilation error

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Finalization;

procedure Test_Hi is

    package Bitter_Truth is

       type Root_Pointer is new Ada.Finalization.Controlled with null 
record;

    end Bitter_Truth;

    generic
       type Root_Pointer is private; -- but not tagged private
    package Sweet_Lie is

       type Derived_Horizontally is new Root_Pointer; -- without with

       procedure New_Selector (Arg : in out Derived_Horizontally);

    end;

    package body Sweet_Lie is

       procedure New_Selector (Arg : in out Derived_Horizontally) is
       begin
          Put_Line ("Hello, World!");
       end New_Selector;

    end Sweet_Lie;

    package End_Result is new Sweet_Lie (Bitter_Truth.Root_Pointer);

    use End_Result;

    Born_As_Root_Pointer : Bitter_Truth.Root_Pointer;
    Type_Casted : Derived_Horizontally;

begin
    Type_Casted := Derived_Horizontally (Born_As_Root_Pointer);
    Type_Casted.New_Selector;

end Test_Hi;


-- 
If you want to get to the top, you have to start at the bottom
kazakov1961
Re: [ada_ru] Re: Как лучше объявлять умные указатели?
2013-01-30 13:36:38
On Wed, 30 Jan 2013 19:57:30 +0700, you wrote:

> Попытался добавить примитивную операцию внутри generic, который не знает 
> о том, что его private параметризующий тип tagged. Получаю ошибку 
> подстановки :(

Так и должно быть. Слава Богу.

> type Root Pointer is new Ada.Finalization.Controlled with null 
> record;

Не надо так делать. Общий корень для указателей абсолютно бессмысленен и
равно бесполезен.

(Если счетчик ссылок хочется хранить вне объекта, это делается через
Storage Pool. Техника та же как и для списков и графов. Примеры там же.)

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
Иван Леваше
Re: Как лучше объявлять умные указатели?
2013-01-30 14:27:20
30.01.2013 16:15, Dmitry A. Kazakov пишет:
>> В Аda 2012 появляется subtype predicates. Static_Predicate можно,
>> похоже, использовать для проверки на принадлежность к подклассу.
>> Красивых селекторов для subtype при этом не получится. Даже, если писать
>> .Data., Data будет access Root_Class'Class, его нужно будет приводить к
>> access Derived_Class'Class и только тогда вызывать метод. Плохо, что
>> селекторы не могут быть у подтипов иначе, чем через Implicit_Dereference.
>>
>> type is new для не-tagged типов oтлично бы подошли в сочетании с subtype
>> predicates, если бы только у не–tagged типов были селекторы.
>
> Да, это была одна из самых тяжелых ошибок дизайна ada.
>
Если забыть про внешние (COM, SOM, NSObject) ссылки со счётчиками, ещё 
один вариант — дать возможность делать access types Controlled. Как 
Storage_Pool можно назначить через for use, так и Finalize с Adjust'ом. 
Вот тогда бы замечательно всё вписалось в существующий дизайн.

-- 
If you want to get to the top, you have to start at the bottom
Vasiliy Fofanov
Re: [ada_ru] Как лучше объявлять умные указатели?
2013-01-30 16:10:54
> [<rant on> Конкретно, хочу обсуждения развития системы типов Ады.
> Ограничения - один из ее механизмов. Предложения писать бесполезно, если
> нет интереса. А его явно нет. Не хочу заплаток типа аспектов, динамических
> предикатов и т.п. разрушающих единство языка. Т.к. вопрос очень сложен, его
> нельзя решить в рамках AI. AI - хороши только для заплаток, и только
> заплатки проходят через этот механизм. Нужна программа переработки языка и
> лидеры типа Ichbiah и Taft-a. <rant off>]

Дмитрий, во-первых, почему же rant, я вполне согласен с вами насчет разрушающих единство языка
заплаток. Моя первая и последняя любовь - это Ада 95, все последующее радует не более чем
наполовину. Насчет же лидеров типа Ишбиа и Тафта, ну с Ишбиа понятно ничего не получится, а Тафт
никуда не делся и даже напротив приблизился, и может быть найден по адресу [email protected] ;)

> Касательно ограничений, желательно
> 
> 1. Трактовка T как ограниченного T'Class. Разумеется через дискриминант
> типа Tag.
> 
> 2. Возможность распространения ограничения на компоненты типа. Например:
> 
>   type T_Class_Array (What : Tag) is
>      array (Positive range <>) of T'Class (What);
> 
>   type S is new T with ...;
>   subtype S_Array is T_Class_Array (S'Tag); -- Ограничили элементы до S
> 
> 3. Разумеется, границы массивов тоже должны быть дискриминантами.
> 
> 4. Должен присутствовать механизм удаления статического ограничения из
> представления, как это делается в случае границ массивов.
> 
> В частности, 1+4 дает классы для всех типов. Например, Boolean'Class
> содержит тэг, в Boolean он удален т.к. статически известен.

Вы не хотите оформить это в виде содержательного полноценного предложения, и прислать это нам на
report@ ? Для Ады 2012 понятно что поезд ушел, но для Ады 2020 почему бы и нет.

ВФ.
Иван Леваше
Re: Как лучше объявлять умные указатели? m4?
2013-01-31 17:27:54
30.01.2013 16:15, Dmitry A. Kazakov пишет:
> Будет. Эта схема действительно реализована в реальном проекте.
>
> GNAT-у требуется более 2Гб памяти для его компиляции! Так что под Win32 он
> вылетает. Но под Win64 справляется.
>
> Конечно, сотни (может и тысяча, не считал) генериков - удовольствие ниже
> среднего.

Мда.

Попробовал пока что–нибудь изобразить, делая умные указатели 
независимыми типами без общего корня, где делегирование промежуточных 
классов сделано в виде mix-in. Наблюдаю такие проблемы: единственный 
способ copy-paste в Ada — это type is new. При этом больше всего 
страдают примитивные функции, возвращающие желаемый тип. Лучше всего, 
если возвращается сразу нужный тип, но он ещё не готов. После любого 
mix-in может быть следующий mix-in. Наверное, можно возвращать 'Class и 
как–нибудь извратиться с Generic Dispatching Constructor, чтоб в 
run-time инициализировать внутреннюю переменную тегом окончательного 
умного указателя.

Если делать промежуточные типы абстрактными (и функции тоже), при 
окончательном наследовании придётся предоставить каждую такую функцию, 
автоматом это не произойдёт. Смысл generic'ов теряется.

Захотелось пойти другим путём: взять m4. Было бы неплохо интегрировать 
m4 в процесс сборки, как amoc. И вроде бы я видел m4 в списке 
поддерживаемых. С чего начать?

-- 
If you want to get to the top, you have to start at the bottom
Иван Леваше
Re: Как лучше объявлять умные указатели?
2013-02-03 14:58:49
Dmitry A. Kazakov пишет:
> Тут limited private:
> 
> http://www.dmitry-kazakov.de/ada/components.htm#Objects_etc

Последний раз, когда смотрел, не платформо–зависимая реализация 
счётчиков была (без intrinsics).

И ещё: я у себя вместо Invalidate, Is_Valid, Empty и прочего, объявил 
указатель на значение, которое невозможно создать, и у меня красиво 
получаются вещи типа if X = null then (операция сравнения с реальным 
вложенным типом у меня для красоты наружу не торчит), а также +null 
вместо Empty.

 > type Object_Type (<>) is abstract new Entity with private;

Вот это мне не подходит. Мне удалось побороть одну из взаимных 
зависимостей, отказавшись давать generic внутренний тип. Для борьбы с 
циклом я использую limited view, при котором incomplete type можно 
передать в generic только в Ada 2012, как type Object_Type; или type 
Object_Type is tagged;

Я пока стараюсь Ada 2005 ограничиваться, и поэтому я беру только 
Object_Type_Ptr.

>> Непонятно, как лучше объявлять типы, которые будут сидеть в динамической 
>> памяти, и как объявлять умные указатели для них. На первый взгляд 
>> кажется, что нужно делать параллельные иерархии: иерархия умных 
>> указателей дублирует иерархию типов в динамической памяти.
> 
> В Аде 2005 есть interfaces, что частично решает проблему через делегацию:

Интерфейсы мне пригодились, правда, в совсем другом качестве. У меня 
возникли циклические зависимости ещё в одном месте: у держателя 
соединения есть Get_Pool, а у пула есть New_Database, который создаст 
новый держатель. Вызов метода через точку среди копируемых типов есть 
только у tagged, а среди tagged только интерфейсы подходят для таких 
циклических зависимостей. У tagged record ошибка formal parameter "A" 
cannot be used before end of specification

Так что я смог (не до конца) разрешить эту зависимость только через 
интерфейсы. Примерно так:

https://bitbucket.org/OCTAGRAM/mutual-dependent-tagged-types/src/1bf7c0576790538cb0ba9a98188742ee7c7bf63b/Mutual.Main.adb?at=default

Приходится в самом конце приведение типов делать.

Полностью этот цикл можно разрешить, наверное, только в Ada 2012, через 
Implicit_Dereference. Типы, объявляемые как авто–разыменовываемые, 
требуют access, а для access можно использовать неполный тип.

-- 
If you want to get to the top, you have to start at the bottom
Иван Леваше
Re: Как лучше объявлять умные указатели?
2013-02-04 03:32:42
Иван Левашев пишет:
> У tagged record ошибка formal parameter "A" cannot be used before end
> of specification
> 
> Так что я смог (не до конца) разрешить эту зависимость только через 
> интерфейсы

Разобрался. Оказывается, проблема не в том, что tagged records в одном 
пакете не замораживаются до конца пакета, а в том, что они объявлялись 
как tagged private или Уже_Известный_Тип with private, а надо 
Уже_Известный_Тип with null record. Если всем показать, что там только 
null record добавился — тогда работает. Долго же я с этим парился...

-- 
If you want to get to the top, you have to start at the bottom
kazakov1961
Re: [ada_ru] Re: Как лучше объявлять умные указатели?
2013-02-04 08:53:19
On Sun, 03 Feb 2013 21:58:49 +0700, you wrote:

> Dmitry A. Kazakov пишет:
>> Тут limited private:
>> 
>> http://www.dmitry-kazakov.de/ada/components.htm#Objects etc
> 
> Последний раз, когда смотрел, не платформо–зависимая реализация 
> счётчиков была (без intrinsics).

Не понял.

> И ещё: я у себя вместо Invalidate, Is Valid, Empty и прочего, объявил 
> указатель на значение, которое невозможно создать,

Указатель не может показывать на невозможный объект, если не через
Unchecked Conversion, конечно.

Имеется вариант с not null access, когда ссылка инициализируется
stock-объектом. Это работает, но довольно крупный геморрой. И требует Ады
2005 (Simple Components придерживается ada). Теоретически, это должно
устранять проверку на null. На практике, не смотрел, что генерирует GNAT, -
лень. А так, - работает.

>  > type Object Type (<>) is abstract new Entity with private;
> 
> Вот это мне не подходит. Мне удалось побороть одну из взаимных 
> зависимостей, отказавшись давать generic внутренний тип. Для борьбы с 
> циклом я использую limited view, при котором incomplete type можно 
> передать в generic только в Ada 2012, как type Object Type; или type 
> Object Type is tagged;

Не могу судить, я никогда не использую limited view для борьбы с
зависимостями и вообще.

Общая база нужна для хранения счетчика и операций сравнения, которые
требуются для упорядоченный множеств.

> У tagged record ошибка formal parameter "A" 
> cannot be used before end of specification

Просто, не надо пользовать генерики для типов имеющих приватную часть в
открытой части пакета где этот тип создается.

> Приходится в самом конце приведение типов делать.

Downcast - совсем нехорошо. Медленно и грязно.

> Полностью этот цикл можно разрешить, наверное, только в Ada 2012, через 
> Implicit Dereference. Типы, объявляемые как авто–разыменовываемые, 
> требуют access, а для access можно использовать неполный тип.

Сомневаюсь. Мне не показалось, что Implicit Dereference что-то дает для
указателей. Могу ошибаться. Общая проблема - анонимность access type
объекта, который ссылка должна убивать когда счетчик обнуляется, при том,
что сам указатель дискриминант, а не компонента. Можно это все обойти, но -
дикая грязь.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
Иван Леваше
Re: Как лучше объявлять умные указатели?
2013-02-04 16:49:04
Dmitry A. Kazakov пишет:
> On Sun, 03 Feb 2013 21:58:49 +0700, you wrote:
> 
>> Dmitry A. Kazakov пишет:
>>> Тут limited private:
>>>
>>> http://www.dmitry-kazakov.de/ada/components.htm#Objects_etc
>> Последний раз, когда смотрел, не платформо–зависимая реализация 
>> счётчиков была (без intrinsics).
> 
> Не понял.

LOCK XCHG ADD или интринсик gcc не применяется

> 
>> И ещё: я у себя вместо Invalidate, Is_Valid, Empty и прочего, объявил 
>> указатель на значение, которое невозможно создать,
> 
> Указатель не может показывать на невозможный объект, если не через
> Unchecked_Conversion, конечно.

У этого указателя единственное значение — null. Не показывая всем подряд 
внутренний указатель, я могу перегружать "=", чтобы сравнивать с null и 
перегрузить "+", чтобы создать никуда не указывающий умный указатель.

Вместо A.Invalidate получается A := +null;

> 
> Имеется вариант с not null access, когда ссылка инициализируется
> stock-объектом. Это работает, но довольно крупный геморрой. И требует Ады
> 2005 (Simple Components придерживается ada). Теоретически, это должно
> устранять проверку на null. На практике, не смотрел, что генерирует GNAT, -
> лень. А так, - работает.

А с выходом ObjectAda для 2005го стандарта что–нибудь изменится?

> Сомневаюсь. Мне не показалось, что Implicit_Dereference что-то дает для
> указателей. Могу ошибаться. Общая проблема - анонимность access type
> объекта, который ссылка должна убивать когда счетчик обнуляется, при том,
> что сам указатель дискриминант, а не компонента. Можно это все обойти, но -
> дикая грязь.
> 
Ну, пятью часами ранее я написал, как всё–таки можно в Ada 2005 сделать 
по–настоящему нормальные умные указатели (если не оглядываться на 
рутинный код, генерацию которого я ещё не автоматизировал). Чертовски 
неочевидно.

Вот теперь бы это в COM и SOM утилитах для Ады воплотить, но пока не до 
того.

-- 
If you want to get to the top, you have to start at the bottom
kazakov1961
Re: [ada_ru] Re: Как лучше объявлять умные указатели?
2013-02-04 18:28:37
On Mon, 04 Feb 2013 23:49:04 +0700, you wrote:

> Dmitry A. Kazakov пишет:
>> On Sun, 03 Feb 2013 21:58:49 +0700, you wrote:
>> 
>>> Dmitry A. Kazakov пишет:
>>>> Тут limited private:
>>>>
>>>> http://www.dmitry-kazakov.de/ada/components.htm#Objects etc
>>> Последний раз, когда смотрел, не платформо–зависимая реализация 
>>> счётчиков была (без intrinsics).
>> 
>> Не понял.
> 
> LOCK XCHG ADD или интринсик gcc не применяется

И как это касается Ады?

> У этого указателя единственное значение — null. Не показывая всем подряд 
> внутренний указатель, я могу перегружать "=", чтобы сравнивать с null и 
> перегрузить "+", чтобы создать никуда не указывающий умный указатель.
> 
> Вместо A.Invalidate получается A := +null;

Жуть! Но, если хочется, то чем плохо A.Set (null);?

> А с выходом ObjectAda для 2005го стандарта что–нибудь изменится?

В каком плане?

ObjectAda растерял всю клиентскую базу, мою контору, например. Если их
новый владелец хочет ее вернуть, то начинать им придется сразу с Ады 2012,
с кросс компиляторов для встроенных приложений за 500 тугриков. Не потянут
они!

А, вообще, забавные ребята. Они оказывается еще и Apex Ada купили.
Интересно, только права, или еще и людишек.

> Вот теперь бы это в COM и SOM утилитах для Ады воплотить, но пока не до 
> того.

Для bindings ничего этого не надо. Указатели прячутся в приватную часть,
наружу они просто controlled, и чаще limited controlled.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
Новое сообщение:
Страницы: 1

Чтобы оставить новое сообщение необходимо Зарегистрироваться и Войти