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

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 типов были селекторы.

 

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

 

--

Regards,

Dmitry A. Kazakov

http://www.dmitry-kazakov.de

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

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

С уважением,

ВФ

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

30.01.2013 16:15, Dmitry A. Kazakov пишет:

 

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

среднего.

 

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

 

type is new для не-tagged типов oтлично бы подошли в сочетании с subtype

predicates, если бы только у не–tagged типов были селекторы.

 

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

 

Попытался добавить примитивную операцию внутри 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

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

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 типов были селекторы.

 

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

 

Если забыть про внешние (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

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

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

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

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 почему бы и нет.

ВФ.

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

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

Иван Левашев пишет:

У 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

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 придерживается Ады 95). Теоретически, это должно устранять проверку на 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

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 придерживается Ады 95). Теоретически, это должно

устранять проверку на 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

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

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