Ада 2012 - заменить Fixed_Decimal_Type'Round () настроенной версией? - PullRequest
2 голосов
/ 16 октября 2019

Недавно я имел радостный успех, когда предоставил собственную процедуру 'Write () замены для пользовательского типа записи, такого как ...

   type Pixel_Format is
      record
         --  blah blah
      end record;

   procedure Pixel_Format_Write (
     Stream : not null access Root_Stream_Type'Class;
     Item : in Pixel_Format);

   for Pixel_Format'Write use Pixel_Format_Write;

. Я использовал это для преобразования определенных членов записи из мало-от байтов до байтов при записи в сетевой поток. Работал прекрасно.

При том же размышлении я подумал, можно ли заменить функцию 'Round () десятичных типов с фиксированной запятой, поэтому я попытался провести быстрый и грязный тест ...

   --  This is a "Decimal Fixed Point" type
   type Money_Dec_Type is delta 0.001 digits 14;

   --  ...

   function Money_CustomRound(X : in Money_Dec_Type)
     return Money_Dec_Type'Base;

   for Money_Dec_Type'Round use Money_CustomRound; -- COMPILER COMPLAINS HERE

   --  ...

   function Money_CustomRound(X : in Money_Dec_Type)
     return Money_Dec_Type'Base is

     begin
        return 0.001;
   end Money_CustomRound;

Увы, GNAT находит это оскорбление:

attribute "Round" cannot be set with definition clause

Вопрос:

Я пытаюсь сделать невозможное? Или есть способ изменить атрибут 'Round по умолчанию так же, как возможно изменение 'Write?

Контекст к вопросу:

Iиметь набор из 15 различных способов округления валютных значений, которые меняются от одного проекта к другому (иногда в рамках одного проекта!). Примеры включают в себя:

  • Круглые половинки от нуля (похоже, по умолчанию Ада)
  • Круглые половинки до нуля
  • Статистические (реентерабельный тип, который требует глобального обслуживания)
  • Округление в сторону четности ИЛИ шансы
  • Округление в сторону + INF / -INF
  • ...

Это был бы мощный инструмент дляиметь возможность сделать этот вид функциональности прозрачным для программиста, используя определенные методы округления, определенные на уровне общего пакета.

Ангел на моем другом плече предлагает мне попросить что-то совершенно безумное.

Мне интересно это, потому что документация (ALRM и "Barnes 2012") дает спецификацию функции для процедуры по умолчанию. Зачем им это делать, если один не может заменить его другим по собственному замыслу?

1 Ответ

4 голосов
/ 16 октября 2019

Нет, вы не можете переопределить атрибут Round. Атрибуты могут быть запрошены только (см. RM K.2 ). Только аспекты могут быть (пере) определены с использованием спецификации аспектов (см. RM K.1 ; применяются некоторые исключения). RM дает спецификации функций, стоящих за атрибутами, чтобы прояснить подписи для читателя.

...