Загрузка данных


unit FixedStack;

{$mode objfpc}{$H+}
{$codepage UTF-8}

interface

uses
  {$ifdef unix}cwstring,{$endif}
  SysUtils;

type
  { --- Шаг 1. Классы исключений --- }
  
  // Базовый класс для всех ошибок стека
  EStackError = class(Exception);

  // Исключение при опустошении стека
  EStackUnderflowError = class(EStackError);

  // Исключение при переполнении стека (с дополнительным свойством)
  EStackOverflowError = class(EStackError)
  private
    FCapacity: Integer; // Внутреннее поле для хранения емкости
  public
    constructor Create(ACapacity: Integer);
    property Capacity: Integer read FCapacity; // Свойство для доступа извне
  end;

  { --- Шаг 2. Класс фиксированного стека --- }
  
  TFixedStack = class
  private
    FData: array of Integer; // Динамический массив, размер которого зафиксируем
    FTop: Integer;           // Индекс верхнего элемента (если -1, то стек пуст)
    FCapacity: Integer;      // Максимальная емкость стека
    
    function GetCount: Integer;
    function GetIsEmpty: Boolean;
    function GetIsFull: Boolean;
  public
    constructor Create(ACapacity: Integer);
    destructor Destroy; override;
    
    procedure Push(AValue: Integer);
    function Pop: Integer;
    function Peek: Integer;
    
    property Count: Integer read GetCount;
    property Capacity: Integer read FCapacity;
    property IsEmpty: Boolean read GetIsEmpty;
    property IsFull: Boolean read GetIsFull;
  end;

implementation

{ EStackOverflowError }

constructor EStackOverflowError.Create(ACapacity: Integer);
begin
  // Вызываем конструктор предка и передаем туда отформатированное сообщение
  inherited Create(Format('стек заполнен (ёмкость: %d)', [ACapacity]));
  FCapacity := ACapacity;
end;

{ TFixedStack }

constructor TFixedStack.Create(ACapacity: Integer);
begin
  if ACapacity <= 0 then
    raise EStackError.Create('Емкость стека должна быть больше нуля');
    
  FCapacity := ACapacity;
  SetLength(FData, FCapacity); // Выделяем память под массив
  FTop := -1;                  // Стек изначально пуст
end;

destructor TFixedStack.Destroy;
begin
  SetLength(FData, 0); // Освобождаем массив
  inherited Destroy;
end;

procedure TFixedStack.Push(AValue: Integer);
begin
  if IsFull then
    raise EStackOverflowError.Create(FCapacity);
    
  Inc(FTop);          // Двигаем указатель вершины вверх
  FData[FTop] := AValue; // Записываем значение
end;

function TFixedStack.Pop: Integer;
begin
  if IsEmpty then
    raise EStackUnderflowError.Create('стек пуст');
    
  Result := FData[FTop]; // Забираем значение с вершины
  Dec(FTop);             // Двигаем указатель вершины вниз
end;

function TFixedStack.Peek: Integer;
begin
  if IsEmpty then
    raise EStackUnderflowError.Create('стек пуст');
    
  Result := FData[FTop]; // Просто возвращаем значение, не двигая указатель
end;

{ Геттеры свойств }

function TFixedStack.GetCount: Integer;
begin
  Result := FTop + 1;
end;

function TFixedStack.GetIsEmpty: Boolean;
begin
  Result := (FTop = -1);
end;

function TFixedStack.GetIsFull: Boolean;
begin
  Result := (GetCount = FCapacity);
end;

end.