Przyszło mi do głowy jak na to spojrzałem i sam nie wiem jeszcze, czy by coś uprościło albo ukulturalniło.
W faccposix.cc, wydaje mi się, że casty static_cast(-1) są nadmiarowe, bo skoro result jest auto (czyli off_t), to przy porównaniu się int -1 odpowiednio sam "promuje" do większego typu jeśli to będzie potrzebne.
Zastanawiam się, czy nie chciałbyś sobie zrobić dziedziczenia po std::streambuf gdzieś.
Patrzę w faccbindev.cc, tam są syscalle na fd. Jeszcze zanim te syscalle: konstruktor binadyDeviceAccessor() jak przyjmie stringa przez kopię bez const (bo już przyjmuje kopię, ale const) to można go std::move() do środka. Użycie ::open() spoko, tylko dla pełnej paranoi można by sprawdzić co zwraca. W ::fileName() wygląda, jakby można było zwrócić stringa przez const-ref i całą metodę opatrzyć kwalifikatorem const. W linii 42. i dalej jest potencjalnie podejrzanie.
A ten unique_ptr w linii 399, na którym natychmiast jest robiony .release()...? Wygląda jakby nic nie robiło, tzn. było analogiczne do walnięcia gołego new synsugar..., bo skoro i tak robimy release() na tym, to to jest noop.
W sensie, te dwa fragmenty są semantycznie równoważne:
T *ptr = std::unique_ptr<T>(new T{}).release();
T *ptr = new T{};
No i wtedy pytanie czy tam coś nie cieknie. Jak read() zwróci -1, to read_size się przekręci na dużą liczbę.
descriptor.cc:430 stringa name można przez std::move() popchnąć do konstruktora Description, aczkolwiek to pewnie będzie redundantne w świetle przejścia na string_view. To kombinowanie z podmienianiem locale wygląda trochę...dziwnie.
BTW, te funkcje ltrim() i rtrim() w descriptor.cc też można wygodnie opędzić na std::string_view. To ostatnie ma metody remove_prefix(), remove_suffix(), a że działają na widoku, a nie fizycznym stringu, to są mega tanie.
descriptor.cc:49, w funkcji GetFieldType(), słownik typeDictionary bym zmienił na static const, bo teraz wygląda, jakby się za każdym razem budował przy wywołaniu funkcji.
Przy czym ten const spowoduje, że trzeba będzie operator[] zmienić na .at().
I jeśli na wejściu może być typ "nieobsługiwany", to sprawdzić jego obecność w słowniku, żeby wyjątek nie poleciał na .at().
Analogicznie w następnej funkcji GetFieldType().
No dokładnie, nagle cała masa rzeczy po prostu zniknie.
W konstruktorze Descriptor, ten co przyjmuje cztery parametry - wydaje mi się, że można w jego ciele zmienić
push_back(rField(n, l, a, t));
na
emplace_back(n, l, a, t);
I wtedy idąc dalej: jak przyjąć parametr std::string n przez kopię, to:
emplace_back(std::move(n), l, a, t);
Swoją drogą, dziedziczenie po kontenerach z STL jest generalnie odradzane, ale nie to, że nie wolno.
Tylko trzeba uważać na destruktory.
W liniach 133. i 134. - może też się da (odpowiednio) emplace_back() i .emplace() (albo .try_emplace())?
W tej pierwszej funkcji idzie std::string przez kopię, no ale to rozumiem, że do celów trimowania. Jak by to był string_view, to wszystko się zrobi tanie.
* Bym przemigrował większość stringów na std::string_view, żeby nie walić w stertę.
_Originally posted by @michalwidera in https://github.com/michalwidera/retractordb/issues/7#issuecomment-2115924549_
@szreder - Wielkie dzięki!
No i wtedy pytanie czy tam coś nie cieknie. Jak read() zwróci -1, to read_size się przekręci na dużą liczbę.
push_back(rField(n, l, a, t));
naemplace_back(n, l, a, t);
I wtedy idąc dalej: jak przyjąć parametr std::string n przez kopię, to: emplace_back(std::move(n), l, a, t); Swoją drogą, dziedziczenie po kontenerach z STL jest generalnie odradzane, ale nie to, że nie wolno. Tylko trzeba uważać na destruktory. W liniach 133. i 134. - może też się da (odpowiednio) emplace_back() i .emplace() (albo .try_emplace())? W tej pierwszej funkcji idzie std::string przez kopię, no ale to rozumiem, że do celów trimowania. Jak by to był string_view, to wszystko się zrobi tanie.Cake c; c = Cake::Cheese; std::cout << static_cast<const char >(c) << '\n'; c = Cake::fromString("Chocolate"); std::cout << static_cast<const char *>(c) << '\n';