# 4 Pomůcky

## 4.1 Přidělování unikátních hodnot

Pro realizaci vektorů atributů (odst. XXX) potřebujeme:

- proměnné pro indexaci vektoru, jejichž typ bude specifický pro vektor v dané třídě
- konstanty, které budou v rámci tohoto typu unikátní.

`AttrIndex<Key>` | `attr.h`

Typ proměnné je realizován šablonou AttrIndex. Objekty této třídy nesou celočíselnou hodnotu a jsou vybaveny základními metodami:

- srovnání: operator == () a operator < ()
- přiřazení: operator = () a kopírovací konstruktor

Parametr šablony Key odlišuje proměnné různých typů, které pak nelze vzájemně přiřadit. Je možno použít libovolný typ, ale zpravidla se používá třída, jejímž členem je indexovaný vektor.

AttrUnique<Key>`` | `attr.h`
`StatAttrUnique``<Key>```

Třída AttrUnique dědí AttrIndex a realizuje proměnnou, která při inicializaci nabyde hodnoty, unikátní mezi všemi objekty této třídy. Po zániku objektu je hodnota volná a může být (nikoli nutně musí) být přidělena jinému objektu. Jestliže přiřazení takto inicializované proměnné je nežádoucí (má to být konstanta), stačí ji deklarovat jako const.

Třída StatAttrUnique je shodná s AttrUnique až na to, že je určena k inicializaci v čase inicializace modulu, to jest jako statická proměnná modulu. Objekty této třídy nemohou být automatickými nebo dynamickými proměnnými.

## 4.2 Registrace funkcí a funktorů v čase inicializace

## 4.3 Multimetody

## 4.4 Množiny

## 4.5 Pojmenované objekty

## 4.6 Číslované objekty

## 4.7 Zazubený výstup

## 4.8 Konstrukce výjimek

### 4.8.1 Princip

- Každá výjimka má

- důvod (I/O, nekonzistence struktur, syntax ... )
- místo (v souboru, v bloku ...)
- kontext
- systémovou kategorii (běhová chyba - std::runtime_error, logická chyba - std::logic_error)

- Třídy reprezentující tyto čtyři komponenty jsou parametry šablony CException. Místo a kategorie mají implicitní prázdné třídy.
- Každá třída výjimky z této šablony odvozená je potomkem tříd systémové kategorie a důvodu.
- Podobjekt výjimky odpovídající systémové kategorii je inicializovány tak, aby metoda what() dala kompletní popis výjimky.

### 4.8.2 Existující komponenty

Druh | Název | Modul | Význam
důvod | IOReason | err.h err.cpp | I/O chyba charakterizovaná systémovou proměnnou errno.
ERCReason | err.h err.cpp | Porušení elektrických pravidel
InconsReason | err.h err.cpp | Nekonzistence datových struktur
TokenReason | lexan.h lexan.cpp | Přišla jiná lexikální jednotka než očekávaná
KWReason | lexan.h lexan.cpp | nesprávné klíčové slovo
NotYetReason | lexan.h lexan.cpp | něco není implementováno
UndInstReason | edif.h edif.cpp | Nedefinovaná instance
UndCellReason | edif.h edif.cpp | Nedefinovanáý blok
pozice | FilePosition | err.h err.cpp | Řádek (je-li znám) a jméno souboru
LexPosition | lexan.h lexan.cpp | Totéž, převzaté z lexikálního analyzátoru; potomek FilePosition
ObjectPosition | device.h device.cpp | Object ve struktuře 1:1
PortPosition | device.h device.cpp | Port a příslušný Object ve struktuře 1:1

### 4.8.3 Definované kombinace komponent

Název | Modul | Syst. kategorie | Důvod | Pozice | Kontext | Použita
IOException | err.h | std::runtime_error | IOReason | FilePosition |  | bench.cpp lexan.cpp UBlif.cpp Upla.cpp
SyntaxException | lexan.h | std::runtime_error | TokenReason | FilePosition |  | bench.cpp edif.cpp lexan.cpp UBlif.cpp Upla.cpp
KWException | lexan.h | std::runtime_error | KWReason | FilePosition |  | bench.cpp edif.cpp
NotYetException | lexan.h | std::runtime_error | NotYetException | FilePosition |  | bench.cpp edif.cpp
ObjIncException | device.h | std::runtime_error | InconsReason | ObjectPosition |  | device.cpp
PortIncException | device.h | std::runtime_error | InconsReason | PortPosition |  | device.cpp
PortERCException | device.h | std::runtime_error | ERCReason | PortPosition |  | device.cpp
UndInstException | edif.h | std::runtime_error | UndInstReson | FilePosition |  |
UndCellException | edif.h | std::runtime_error | UndCellReason | FilePosition |  | edif.cpp
BlifMess | UBlif.h | std::runtime_error | InconsReason | FilePosition |  | UBlif.cpp
PlaMess | UPla.h | std::runtime_error | InconsReason | FilePosition |  | Upla.cpp

### 4.8.4 Použití

- Jednotlivé komponenty výjimky se musí inicializovat pomocnými objekty, tedy např.
  throw IOException ( TokenReason (currentToken, expected), FilePosition (filename, lineno))
- Každá nově definovaná třída důvodu, pozice nebo kontextu musí mít:

- konstruktor, který bere potřebné hodnoty; jestliže tento konstruktor bere (void), musí brát i nevýznamvý parametr např. typu int (jinak překladač nerozpozná, že se konstruuje objekt)
- kopírovací konstruktor
- funkci std::string tell (void), která dodá čitelný popis obsahu objektu

### 4.8.5 Komentáře

- Je to dost užvaněné
- Třída pro důvod by měla také mít metodu what() a skladovat v sobě popis celé výjimky, aby bylo možno psát
  catch (IOReason ior) ...
- Kontexty se nepoužívají a třeba zmizí
- Určitě se má dodělat třída CodePosition, která obvyklým fíglem bere __LINE__ a __FILE__
- Některé výjimky, zvláště s důvodem InconsReason, by se měly přesunout pod std::logic_error