Autowypełnianie tablicy podczas kompilacji programu

0

Otóż ostatnio piszę program obsługujący pewne urządzenie elektroniczne.
Kilka słów opisu. Urządzenie to posiada kilka tysięcy rejestrów (wcale nie mówię że korzystam ze wszystkich :) ), z którego każdy, ma swój unikalny adres i swoją unikalną nazwę oraz odpowiada za jakieś tam zadanie. Rejestry te są niezmienne (adresy i nazwy) oraz większość z nich jest poukładana w logiczne bloki (np są 4 tryby pracy urządzenie gdzie każdy tryb ma dla siebie 100 rejestrów odpowiadających za ustawienia tego trybu)
Więc w aplikacji mam tablicę z nazwami rejestrów i ich adresami oraz mam funkcję która te rejestry uzupełnia (dodaje w odpowiedniej kolejności i nadaje im nazwy).
Teraz w niektórych przypadkach bardzo wygodnie jest używać NAZW tych rejestrów, więc muszę mieć funkcję

int getAdr( const char* regname )

zwracającą adres rejestru wyszukując nazwy w tablicy zawierającej informacje o nich. Mam nadzieję że do tej pory wszystko jest zrozumiałe :)

Ale całkiem niedawno przeczytałem o możliwości obliczania pewnych wartości stałych podczas kompilacji (funkcje z dopiskiem constexpr) i teraz pytanie, czy dało by się uzupełnić tablicę wartościami i następnie w programie (w miejscach gdzie nazwa rejestru jest znana podczas kompilacji oczywiście) zmienić wywołanie funkcji wyszukującej tej nazwy na wynik, czyli po prostu ten wymagany adres? jeżeli tak, to co powinienem szukać (chodzi mi o jakieś przykłady, tutoriale, bo że informacji o samym constexpr to wiem)

Pozdrawiam zawisza :)

0

A czy musisz to tak dziwnie robić i nie wystarczy ci użycie map<string, int> albo lepiej unordered_map<string, int>? Szukanie w pierwszym przypadku to O(log(n)) w drugim O(1) :)

0

Czy muszę? Na pewno nie :D Chodzi bardziej o nauczenie się czegoś nowego, przy takiej ilości rejestrów jakie posiadam i w przypadku kiedy będę ich szukał przez nazwę jakieś może 15 razy podczas startu "okienka" mogę również użyć "brute forca" do wyszukiwania tych rejestrów i też będzie OK,

Dzięki za odpowiedź :)

0

Teraz w niektórych przypadkach bardzo wygodnie jest używać NAZW tych rejestrów, więc muszę mieć funkcję
int getAdr( const char* regname )

A nie wystarczy zwykły enum?

Jak już musisz mieć nazwy, to myślę że unordered_map będzie najlepszy.

Nie widzę jak by tu można zastosować constexpr

Jeśli masz w miarę dobry kompilator to można zrobić nawet tak:

    unordered_map<string,int> mapa =
    {
       { "ala", 42 },
       { "ola", 666 }
    };

… a jeśli masz stary, w którym jest tylko (wolniejsze) map, to znajdziesz unordered_map w bibliotece Boost.

0

Jak masz stałą liczbę tych nazw i ta lista się nie zmienia to można sobie zorganizować coś jak unordered_map tylko lepsze.
Grunt to metodą brute force znaleźć parametry funkcji która skonwertuje ciąg znaków na liczbę (hashowanie) czyli znajdujesz takie które jednoznacznie "mapuje" ci ten zbiór na jak najmniejszą przestrzeń liczb całkowitych.
Funkcje szukasz np taką x(i)=((x(i-1)+znak)*a+b)%(c) - nie jest to najlepsza wersja funkcji haszującej (bo wolna) lecz jako przykład ujdzie.
Po znalezieniu a,b,c wypełniasz tabelkę wartościami portu:
int tb[]={9,3214,345,-3};
Przy dobrym "przecomputing'u" wynik (szybkość) będziesz miał lepszą niż unordered_map.

0

Dzięki, wszystkie wasze pomysły nadają się i na pewno któryś z nich wybiorę.

Nie widzę jak by tu można zastosować constexpr…

Co do constexpr... sądziłem że (w skrócie) informuje on kompilator o tym że dana funkcja może zostać wykonana (obliczona) podczas kompilacji, a do samego programu zostanie "wklejony" sam wynik działania tej funkcji i to właśnie chciałem osiągnąć podczas wyszukiwania adresów po nazwach danych rejestrów

Dzięki za odpowiedzi :)

0

@cszawisza taki coś to i przez #define możesz zrobić ale nie polecałbym ;]

0

:D przez #define to bardzo popularna metoda wśród programujących µC (czyli w sumie też mnie) ale ciężko jest zrobić pętlę robiącą różne #definy a że ja chcę większość rejestrów uzupełniać właśnie w pętli to ciężko by mi było :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1