lundi 6 mars 2017

g++: merge template member function instance

is there any way to have identical member functions of a templated class to be merged in the final binary? I have a class which may support specific features and depended on that, may require some additional steps inside of the member function:

template <uint32_t features>
class Driver {
   bool set (uint32_t value) {
      /* do something required for every feature */
      if (features & Feature::A)
         /* do special things if Feature::A */
      /* do something required for every feature */
      if (features & Feature::B || features & Feature::C)
         /* do something special for either Feature::B or Feature::C */
      return true;
   }
   /* more, similar methods */
};

later in the code, I would then use calls like Driver<Feature::A>::set or Driver<Feature::A | Feature::B>::set depending on the actual available features. All this works well so far, only the emitted code compiled with g++-5.4.0 -std=c++11 -O3 does not merge identical methods how I would like to use it. Having multiple functions in this class with major common parts among them, really blows up the size of the final binary. While using private functions for the common parts reduces the overhead of size but is not as friendly to read in my opinion:

template <uint32_t features>
class Driver {
    void _set_common_0 (value) {
        /* do something required for every feature */
    }
    bool set (uin32_t value) {
        _set_common_0 (value);
        if (features & Feature::A)
            _set_special_0 (value);
        _set_common_1 (value);
        if (features & Feature::B || features & Feature::C)
            _set_special_1 (value);
        return true;
   }
};

Also this introduces problems, if there is an 'early out' path in one of the special parts, which could formerly be done by a simple return and now would be somehow escalated from the sub-functions, introducing further checks depending on the return value of those sub functions...

What I would like to have, is that the compiler emits (on use) symbols for Driver<Feature::B>::set and Driver<Feature::C>::set but let them point to the same code location as they are identical by means of code. Any idea how I could do this? (preferably, staying with c++11 and not require features from a newer standard)

Aucun commentaire:

Enregistrer un commentaire