Stworzyłem klasę, która wygląda jak tablica, ale zamiast przechowywać dane w samym programie, przesyła bajt z pliku (aby zmniejszyć wpływ pamięci RAM). Teraz mam to wszystko działa, ale programista musi określić klasę przy użyciu następujących:Generowanie parametrów szablonu w czasie kompilacji
#define CreateReadOnlyBlock(name, location, size, ...) \
template<> \
const unsigned int ReadOnlyBlock<location, size>::Data[] \
__asm__(".readonly__" #location "__" #name) \
= { __VA_ARGS__ }; \
ReadOnlyBlock<location, size> name;
Przykład:
//A read only array of {0, 1, 2, 3}
CreateReadOnlyBlock(readOnlyArray, 0, 4, 0, 1, 2, 3);
Należy pamiętać, że jest to dla wbudowanego procesora, a dyrektywa asm przechodzi przez narzędzie w asemblerze, aby utworzyć plik tylko do odczytu.
Oto moje pytanie: jak mogę wyeliminować zmienne "lokalizacja" i "rozmiar"? Nienawidzę tego, że programista musi wpisywać je ręcznie, i wolałby, żeby generował je podczas kompilacji. Więc zamiast programatora konieczności wpisywania:
//A read only array at location 0 of {0, 1, 2, 3}
CreateReadOnlyBlock(readOnlyArray1, 0, 4, 0, 1, 2, 3);
//A read only array at location 4 of {4, 5, 6, 7}
CreateReadOnlyBlock(readOnlyArray2, 4, 4, 4, 5, 6, 7);
Mogli po prostu wpisać:
CreateReadOnlyBlock(readOnlyArray1, 0, 1, 2, 3);
CreateReadOnlyBlock(readOnlyArray2, 4, 5, 6, 7);
i odpowiedni stałe byłyby generowane. Zasadniczo szukam sposobu generowania i umieszczania tych stałych na podstawie poprzednich definicji w czasie kompilacji. C++ 11 jest uczciwą grą, po prostu nie jestem do końca obca (coś ze constexpr wydaje się być wiarygodne?). Również C-Preprocessor jest w porządku, jeśli nie czyni go brzydszym, niż już jest. czy to możliwe?
EDIT dla jasności:
W klasie ReadOnlyBlock nie jest to metoda:
template<const int _location, const int _size> class ReadOnlyBlock
{
...
unsigned int operator[] (size_t index)
{
return LoadFromROM(index + _location);
}
}
Jest nieodłącznym współzależność między zmiennej lokalizacji i pliku ROM, że nie mogę myśleć jak złamać. I do mają również pełną kontrolę nad łańcuchem narzędzi, ale potrzebuję sposobu na przekazanie narzędzia asemblera, jak skonstruować plik, a także wskazanie kodu C++, w którym znajdują się bloki.
Kolejny EDIT:
Plik i jego bloki mogą być dość duże, jak 1k słowy, tak dużo preprocesora magii może zwiń skoro. Również dziękuję wszystkim za pomoc do tej pory!
Opcja '# location' w części "__asm__" naprawdę to zabija. Czy naprawdę tego potrzebujesz, czy byłbyś zadowolony z rozwiązania tylko reszty? –
Rozmiar jest łatwy, ale lokalizacja wymaga kontekstu. Inicjowanie szablonów jest językiem funkcjonalnym, a wynik instancji może być różny w zależności od tego, co przekazujesz. Jeśli łączysz takie bloki lub tworzysz pamięć w jednym dużym szablonie, możesz to zrobić. Np. Utwórz "krotkę" tablic tylko do odczytu, każda z lokalizacją i rozmiarem, zaczynając od pewnej lokalizacji i spakowaną. – Yakk
Więc może powinienem był podać przyczynę tego. Przeciążony operator [] w klasie ReadOnlyBlock wywołuje LoadFromROM (index + location); Narzędzie tworzy plik tylko do odczytu, który ma każdy blok w każdej określonej lokalizacji, a klasa wie, aby załadować z tego miejsca. Nie mogę wymyślić sposobu na wyeliminowanie tej współzależności, ale mam pełną kontrolę nad tym narzędziem, a także kod dostępu, więc zmiana go nie jest wykluczona. –