[M$ SPECIFIC]
Больше не надо никаких внешних тулзов и ручного вычищения неиспользуемых заголовков!
Допустим есть следующий заголовок некой библиотеки:
void lib_init();
void lib_deinit();
void lib_f();
Меняем заголовок на следующий:
template<int id> struct lib_helper
{
typedef int fake;
};
template<int id = 0> class lib_ind
{
typedef typename lib_helper<id>::fake fake;
};
template<int id> struct lib_magic
{
lib_magic()
{
#ifdef _MSC_VER
__if_not_exists(lib_helper<id>)
{
// Этот заголовочный файл включён зазря
BOOST_STATIC_ASSERT(false);
}
#endif
}
};
static lib_magic<0> lib_magic_;
lib_ind<> lib_init();
lib_ind<> lib_deinit();
lib_ind<> lib_f();
Уаля! Если этот заголовок включит какая-либо единица трансляции, которая не вызывает ни одной из функций lib_init/lib_deinit/lib_f, то она не скомпилируется!
Несколько замечаний:
1. Этот заголовок можно использовать и с другими компиляторами, благодаря #ifdef _MSC_VER, просто не будет работать фича определения неиспользуемых заголовков
2. Если функции библиотеки должны возвращать какое-то значение, а не void, то это можно легко прикрутить к классу lib_ind, тогда просто функции будут выглядеть как lib_ind<
bool> lib_init()
3. Всю эту бойду можно вынести в отдельный повторноиспользуемый заголовочный файл. Тогда в заголовке библиотеки надо будет написать примерно так:
PREVENT_UNUSED_HEADERS(my_lib_name);
4. Эту технику можно распространить и на заголовочные файлы, которые описывают классы. Но тут надо проявить немного фантазии, куда впихнуть lib_ind<>. Вообще место, куда впихнуть lib_ind<> в каждом конкретном классе, должно быть разным, и будет зависеть от того, что подразумевается под "использованием" класса, т.к. для классов это не так тривиально, как для функций. Например такой вариант:
template<int id = 0>
struct lib_class
{
BOOST_STATIC_ASSERT(!id);
lib_class(lib_ind<> fake = lib_ind<>());
};
требует обязательного создания экземпляров класса. Причём создание, например, указателей на класс не будет засчитываться за использование!
Или можно, например, все функции-члены записать аналогично свободным функциям:
struct lib_class
{
lib_ind<> f1();
lib_ind<> f2();
};