﻿/**
\page doc Dokumentace projektu CXItem

##Základní popis

\c CXItem představuje prvek, ze kterého je možné vytvářet lineární obousměrně vázaný seznam. Obousměrně vázaný seznam se od jednoduchého lineárního seznamu liší tím, že jednotlivé prvky \c CXItem obsahují
nejen odkazy na svoje následníky \c Right, ale také odkazy na své předchůdce \c Left. Tento lineární seznam představuje variantu, kdy poslední prvek odkazuje pomocí ukazatele \c Right sám na sebe zprava a první prvek odkazuje pomocí ukazatele \c Left sám na sebe zleva. Díky této vlastnosti je možné vždy detekovat první i poslední prvky v seznamu. Výhodou tohoto typu seznamu je i skutečnost, že všechny ukazatele vždy odkazují svojí hodnotou na platnou paměť, což je výhodné například při vkládání resp. odstraňování prvků.

\dotfile CXItemList.gv "Příklad lineárního obousměrně vázaného seznamu se čtyřmi prvky \c CXItem"
\n

Specifickým případem lineárního obousměrně vázaného seznamu je seznam s pouze jedním prvkem (tzv. elementární seznam). Kde oba ukazatele odkazují na tentýž prvek.

\dotfile CXItemListPrimitive.gv "Příklad elementárního lineárního obousměrně vázaného seznamu s jedním prvkem \c CXItem"
\n

Výhodou obousměrného seznamu je možnost výpočetně efektivního procházení (tzv. traverzování) seznamem oběma směry. Mezi nevýhody lze uvést vyšší paměťové nároky spojené s existencí dalšího ukazatele (tj. \c Left). Tento nedostatek je v naší implementaci seznamu vyřešen tak, že \c CXItem vlastní pouze jediný tzv. rozdílový ukazatel \ref CXItemBase::iXPtr "iXPtr". Tento ukazatel obsahuje rozdíl adres pravého a levého souseda: <center>\p iXPtr = \c Right - \c Left .</center>

Pokud tedy známe adresu levého souseda \c Left, je možné pomocí hodnoty uložené v rozdílovém ukazateli \p iXPtr určit hodnotu pravého souseda: <center>\c Right = \p iXPtr + \c Left .</center>

A pokud známe adresu pravého souseda \c Right, jsme schopní pomocí hodnoty uložené v rozdílovém ukazateli \p iXPtr určit hodnotu levého souseda: <center>\c Left = \c Right - \p iXPtr .</center>

Pro změnu pouze jedné z hodnot \c Left resp. \c Right v rozdílovém ukazateli \p iXPtr, využijeme tyto vztahy:<center>\p iXPtr += \c RightNew - \c RightOld ,</center> <center>\p iXPtr += \c LeftOld  - \c aLeftNew .</center>


\n
##Popis implementace
V tomto školním C++ projektu je prvek lineárního obousměrně vázaného seznamu realizován jako instance třídy \c CXItem mající předka \c CXItemBase.


###Třída CXItemBase
Třída CXItemBase implementuje všechny vlastnosti, které jsou společné pro jakékoliv prvky lineárního obousměrně vázaného seznamu, tj. obsahuje rozdílový ukazatel \p iXPtr, ze kterého je možné určit odkaz na předchozí prvek \c Left resp. odkaz na následující prvek \c Right.
Dále implementuje mechanismy konstrukce, modifikace hodnot ukazatelů a základní kontrolní mechanismy. Tato třída neobsahuje v definici žádná užitečná data, které by měl každý prvek seznamu obsahovat. Definuje, tak pouze základní rozhraní, které bude společné všem prvkům bez ohledu na typ a množství užitečných dat.

Třída dále obsahuje atribut \ref CXItemBase::iExtraInt "iExtraInt", který je potřebný pro realizaci projektů: __multimnožina__ (_obsahuje počet opakujících se prvků_ \c CXItem _stejné hodnoty_), __mapa__ (_obsahuje hodnotu klíče pro daný prvek_ \c CXItem), __asociativní pole__ (_obsahuje výslednou_ \c int _hodnotu, pro kterou je daný_ \c CXItem _klíčem_), __prioritní fronta__ (_obsahuje hodnotu priority daného prvku_ \c CXItem).


###Třída CXItem
Třída \c CXItem je potomkem třídy CXItemBase a obsahuje tedy všechny vlastnosti, které budou společné všem prvkům lineárního obousměrně vázaného seznamu. Úlohou třídy \c CXItem je doplnit definici prvku seznamu o atribut \p iValue,
jenž představuje užitečná data a která bude každý prvek seznamu obsahovat. Dále je třeba vhodně upravit a doplnit metody určené pro konstrukci a likvidaci prvku tak, aby bylo možné nový prvek efektivně konstruovat a využívat.

Třída \c CXItem je navíc správcem své vlastní hodnoty \p iValue a proto definuje základní metody pro zjištění, nastavení této hodnoty a zároveň zajišťuje pro nadřazené vyšší části programu metody pro porovnání prvků dle této hodnoty,
čímž izoluje nadřazené části od nutnosti znát konkrétní datový typ atributu \p iValue.


###Jmenné prostory CXItem_xxxx (CXItem_bool::CXItem, CXItem_TWeekDay::CXItem)
Návrh programu i Vaše zadání požaduje nezávislost na vnitřní implementaci třídy \c CXItem (konkrétním datovém typu atributu \p iValue). Návrh navíc umožňuje, aby uživatel mohl odkomentováním řádku přepínat
mezi vnitřními implementacemi \c CXItem. Tento mechanismus je zajištěn pomocí definice každé z variant \c CXItem ve vlastním jmenném prostoru \c CXItem_NAZEV_TYPU, díky této skutečnosti může existovat v programu
několik stejně pojmenovaných tříd \c CXItem, neboť názvy existují ve svém vlastním oboru viditelnosti (jmenném prostoru).

Volba dané varianty \c CXItem je potom prováděna v souboru CXItem.h, odkomentovaním toho řádku, který exportuje daný jmenný prostor do globálního prostoru jmen.
\code{.cpp}
using namespace CXItem_bool;
//using namespace CXItem_TWeekDay;
//using namespace CXItem_char;
//using namespace CXItem_int;
//using namespace CXItem_float;
//using namespace CXItem_longdouble;
\endcode


\n
##Realizace dalších variant tříd CXItem
V současnosti projekt obsahuje tyto varianty tříd \c CXItem, z nichž je každá definována ve svém jmenném prostoru:
\li CXItem_bool::CXItem
\li CXItem_TWeekDay::CXItem

Tyto dvě třídy jsou pevně zadány a je zakázáno modifikovat jejich zdrojové texty. Pro každou další variantu \c CXItem nadefinujte nový jmenný prostor \c CXItem_NAZEV_TYPU a v něm implementujte novou variantu třídy \c CXItem.
\note Mechanismus by samozřejmě bylo možné realizovat i zcela automaticky (překladač sám dle potřeby programátora vygeneruje novou variantu třídy \c CXItem pomocí definované šablony, případně bude umožnovat dynamickou identifikaci typu a 
tím umožní mít při běhu programu v jednom seznamu různé varianty prvků \c CXItem.
Obě tyto techniky ovšem svým rozsahem vybočují nad rámec výuky v tomto kurzu a proto jsme se rozhodli se jim v tomto projektu vyhnout.


\n
##Testovací hlavní program
Hlavní program v souboru main.cpp představuje základní sadu testů, které ověřují správnou funkci libovolné varianty třídy \c CXItem. Seznamte se s obsahem hlavního programu a protrasujte si jednotlivá volání.

###Testovací hodnoty
Každá z implementací třídy \c CXItem navíc obsahuje šest základních metod vracející hodnotu datového typu který je vhodný pro vložení do atributu \p iValue. Projděte si uvedené mechanismy a snažte se
pochopit jejich vliv na nezávislost kódu hlavního programu.

Jedná se o tyto metody:
\li \c TestValue0() (např. CXItem_bool::CXItem::TestValue0())
\li \c TestStringValue0() (např. CXItem_bool::CXItem::TestStringValue0)
\li \c TestValue1() (např. CXItem_bool::CXItem::TestValue1)
\li \c TestStringValue1() (např. CXItem_bool::CXItem::TestStringValue1)
\li \c TestValueRandom() (např. CXItem_bool::CXItem::TestValueRandom)
\li \c TestStringRandom() (např. CXItem_bool::CXItem::TestStringValueRandom)

###Další kontrolní vlastnosti prvku
Již základní společná třída CXItemBase (a tedy i každý potomek \c CXItem) obsahuje několik kontrolních a ladících mechanismů, které budete jistě chtít využívat.

\li Prvek při své destrukci kontroluje, zda není součástí seznamu dalších prvků a pokud ano, generuje chybové hlášení případně i výjimku \c std::runtime_error.
\li Prvek vždy ověřuje, že oba jeho ukazatele \c Left, \c Right obsahují odkaz na platnou adresu jiného prvku, každý pokus o nastavení neplatné adresy (\c NULL resp. \c nullptr) generuje výjimku \c std::invalid_argument.
\li Pokud je nastaveno při překladu makro \ref CXITEM_XPTR_CHECKING (což je vždy, mimo překladu do Release verze). Prvek kromě ukazatele \p iXPtr obsahuji i kontrolní (pro Vás ale nedostupné) ukazatele \p iLeft a \p iRight. Při prací s odkazy následně prvek provádí další dodatečné kontroly validity zadávaných ukazatelů a v případě nesrovnalostí generuje výjimku \c std::runtime_error.

###Třída ClassInfo
Třída ClassInfo implementuje mechanismus automatického počítání vzniklých objektů a mechanismus jednoznačné identifikace \ref ClassInfo<>::ID "ID" instancí za běhu programu. Tento mechanismus se Vám bude hodit při ladění programu. Všechny Vaše třídy by měly obsahovat atribut \ref CXItemBase::iInstanceInfo "iInstanceInfo" třídy ClassInfo, čímž zajistíte Vašim třídám tyto ladicí vlastnosti. Samotná třída ClassInfo je definována jako šablona umožňující, vznik různých variant této třídy - (generické programování resp. metaprogramování).

Mezi ladicí metody třídy ClassInfo patří:
\li ClassInfo<T>::Total()  - počítadlo vzniklých instancí třídy T
\li ClassInfo<T>::Living() - počítadlo v daném okamžiku existujících instancí třídy T
\li ClassInfo<T>::ID() resp. \ref CXItem_bool::CXItem::ID "CXItem::ID()", CXItemBase::ID()  - unikátní číselné označení dané instance


\attention Projděte si všechny uvedené kontrolní i ladicí mechanismy, snažte se pochopit jejich smysl a využití při trasování programu. Získané vědomosti se Vám budou rozhodně hodit.


\note 
Hodně štěstí při realizaci Vašeho projektu. Nebojte se, ono to půjde. Hlavně _nepropadejte panice!_ ;-)

Pety.

$Id: Documentation.txt 1 2014-10-29 15:27:54Z petyovsky $
*/
