boost.overloaded_function. WTF implementation is ugly?!
От: niXman Ниоткуда https://github.com/niXman
Дата: 14.09.13 09:59
Оценка: -1 :)
приветствую!

прежде всего, позвольте мне поздравить всех программистов/кодеров/говнокодеров(да, и их тоже. есть надежда что исправятся.) с нашим днем
успеха Вам, коллеги!

итак, к делу.
с того самого момента как в буст была принята boost.overloaded_function, я заглянул в сорцы и окуел! я никак не ожидал там увидеть "это"(смайлик какашки над которой летают мухи).

смотрите сами: 1, 2, 3.

я ожидал там увидеть реализацию на основе fusion::map и К`о.

я не смог найти ни одного аргумента в пользу такой реализации. дело вовсе не в том, что я "боюсь" препроцессора, совсем нет -- я не приемлю препроцессор там, где можно обойтись без него.

найдя немного свободного времени, я зарукоблудил такое.
простой пример:
int add(int a, int b) { return a+b; }
double mul(double a, double b){ return a*b; }

auto func = make_overloaded_function(add, mul);

простой пример из сабжа:
const std::string& identity_s(const std::string& x) { return x; }
int identity_i(int x) { return x; }
double identity_d(double x) { return x; }

auto func = make_overloaded_function(identity_s, identity_i, identity_d);

все, на этом возможности сабжа заканчиваются.
в добавок о всему этому, нужно сказать, что для хранения указателей на функции и функциональные объекты — используется 'boost::function<Sig>'. разгильдяйство какое-то!

в общем, интересно мнение окружающих о сабже, и альтернативной реализации. быть может я чего-то недогоняю?
может быть есть смысл предложить бустовцам заменить сабж на мою реализацию?

спасибо.

зы
дополнительные возможности альтернативной реализации:
1. добавление функции в оверлоадед объект: 'auto func2 = insert(func, f3);'
2. удаление функции из оверлоадед объекта: 'auto func3 = erase(func2, f3);'
3. проверка существования функции с определенной сигнатурой и адресом: 'exists<void(int)>(func3) && exists(func3, f3);'

недоделано:
1. пока невозможно хранить лямбды и функциональные объекты. доделаю, если будет спрос.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re: boost.overloaded_function. WTF implementation is ugly?!
От: jazzer Россия Skype: enerjazzer
Дата: 14.09.13 10:21
Оценка: +1
Здравствуйте, niXman, Вы писали:


X>приветствую!


X>прежде всего, позвольте мне поздравить всех программистов/кодеров/говнокодеров(да, и их тоже. есть надежда что исправятся.) с нашим днем

X>успеха Вам, коллеги!



X>в общем, интересно мнение окружающих о сабже, и альтернативной реализации. быть может я чего-то недогоняю?


Твой вариант работает на С++03?
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: boost.overloaded_function. WTF implementation is ugly?!
От: niXman Ниоткуда https://github.com/niXman
Дата: 14.09.13 10:22
Оценка:
хотел привести пример препроцессированного кода, но оказывается, немогу даже банальный пример из сабжа скомпилить %)
#include <boost/functional/overloaded_function.hpp>

int add(int a, int b) { return a+b; }

int main() {
        auto func = boost::make_overloaded_function(add);
        return func(2, 2);
}

получаю:
overloaded.cpp: In function 'int main()':
overloaded.cpp:7:49: error: no matching function for call to 'make_overloaded_function(int (&)(int, int))'
  auto func = boost::make_overloaded_function(add);
                                                 ^
overloaded.cpp:7:49: note: candidates are:
In file included from d:\mingw64\x86_64-w64-mingw32\include\boost\preprocessor\iteration\detail\iter\forward1.hpp:57:0,
                 from d:\mingw64\x86_64-w64-mingw32\include\boost\functional\overloaded_function.hpp:91,
                 from overloaded.cpp:2:
d:\mingw64\x86_64-w64-mingw32\include\boost\functional\overloaded_function.hpp:164:3: note: template<class F0, class F1, class F2, class F3, class F4> boost::overloaded_function<typename boost::overloaded_function_detail::function_type<F>::type, typename boost::overloaded_function_detail::function_type<F1>::type, typename boost::overloaded_function_detail::function_type<F2>::type, typename boost::overloaded_function_detail::function_type<F3>::type, typename boost::overloaded_function_detail::function_type<F4>::type> boost::make_overloaded_function(F0, F1, F2, F3, F4)
 > make_overloaded_function(
   ^
d:\mingw64\x86_64-w64-mingw32\include\boost\functional\overloaded_function.hpp:164:3: note:   template argument deduction/substitution failed:
overloaded.cpp:7:49: note:   candidate expects 5 arguments, 1 provided
  auto func = boost::make_overloaded_function(add);
                                                 ^
In file included from d:\mingw64\x86_64-w64-mingw32\include\boost\preprocessor\iteration\detail\iter\forward1.hpp:62:0,
                 from d:\mingw64\x86_64-w64-mingw32\include\boost\functional\overloaded_function.hpp:91,
                 from overloaded.cpp:2:
d:\mingw64\x86_64-w64-mingw32\include\boost\functional\overloaded_function.hpp:164:3: note: template<class F0, class F1, class F2, class F3> boost::overloaded_function<typename boost::overloaded_function_detail::function_type<F>::type, typename boost::overloaded_function_detail::function_type<F1>::type, typename boost::overloaded_function_detail::function_type<F2>::type, typename boost::overloaded_function_detail::function_type<F3>::type> boost::make_overloaded_function(F0, F1, F2, F3)
 > make_overloaded_function(
   ^
d:\mingw64\x86_64-w64-mingw32\include\boost\functional\overloaded_function.hpp:164:3: note:   template argument deduction/substitution failed:
overloaded.cpp:7:49: note:   candidate expects 4 arguments, 1 provided
  auto func = boost::make_overloaded_function(add);
                                                 ^
In file included from d:\mingw64\x86_64-w64-mingw32\include\boost\preprocessor\iteration\detail\iter\forward1.hpp:67:0,
                 from d:\mingw64\x86_64-w64-mingw32\include\boost\functional\overloaded_function.hpp:91,
                 from overloaded.cpp:2:
d:\mingw64\x86_64-w64-mingw32\include\boost\functional\overloaded_function.hpp:164:3: note: template<class F0, class F1, class F2> boost::overloaded_function<typename boost::overloaded_function_detail::function_type<F>::type, typename boost::overloaded_function_detail::function_type<F1>::type, typename boost::overloaded_function_detail::function_type<F2>::type> boost::make_overloaded_function(F0, F1, F2)
 > make_overloaded_function(
   ^
d:\mingw64\x86_64-w64-mingw32\include\boost\functional\overloaded_function.hpp:164:3: note:   template argument deduction/substitution failed:
overloaded.cpp:7:49: note:   candidate expects 3 arguments, 1 provided
  auto func = boost::make_overloaded_function(add);
                                                 ^
In file included from d:\mingw64\x86_64-w64-mingw32\include\boost\preprocessor\iteration\detail\iter\forward1.hpp:72:0,
                 from d:\mingw64\x86_64-w64-mingw32\include\boost\functional\overloaded_function.hpp:91,
                 from overloaded.cpp:2:
d:\mingw64\x86_64-w64-mingw32\include\boost\functional\overloaded_function.hpp:164:3: note: template<class F0, class F1> boost::overloaded_function<typename boost::overloaded_function_detail::function_type<F>::type, typename boost::overloaded_function_detail::function_type<F1>::type> boost::make_overloaded_function(F0, F1)
 > make_overloaded_function(
   ^
d:\mingw64\x86_64-w64-mingw32\include\boost\functional\overloaded_function.hpp:164:3: note:   template argument deduction/substitution failed:
overloaded.cpp:7:49: note:   candidate expects 2 arguments, 1 provided
  auto func = boost::make_overloaded_function(add);
                                                 ^
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[2]: boost.overloaded_function. WTF implementation is ugly?!
От: niXman Ниоткуда https://github.com/niXman
Дата: 14.09.13 10:24
Оценка: -1
Здравствуйте, jazzer, Вы писали:

J>Твой вариант работает на С++03?

нет, но может. там не много переделывать, однако.
т.е. да, возможно это одно из требований. но все равно не понятно, почему не используется fusion::map...
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[3]: boost.overloaded_function. WTF implementation is ugly?!
От: jazzer Россия Skype: enerjazzer
Дата: 14.09.13 10:31
Оценка: +1
Здравствуйте, niXman, Вы писали:

X>Здравствуйте, jazzer, Вы писали:


J>>Твой вариант работает на С++03?

X>нет, но может. там не много переделывать, однако.
X>т.е. да, возможно это одно из требований. но все равно не понятно, почему не используется fusion::map...

Возможно, что лишнюю зависимость не тянуть.

Понимаешь, относительно буста есть две конфликтующих хотелки.
С одной стороны, постоянно раздаются вопли, что буст слишком большой и невозможно взять из него только одну библиотеку, так как она потянет за собой еще добрый десяток вроде бы не относящихся к делу.
С другой стороны, буст — это куча библиотек для _повторного_ использования. И более чем логично им использовать друг друга внутри (меньше кода, меньше багов). Но тогда всё становится связанным со всем и буст становится монолитным. (К слову, меня это нисколько не парит — мне гораздо легче накатить оттестированный ежеквартальный релиз целиком, чем апдейтить библиотеки по одной с неизвестно какой совместимостью между разными их версиями)
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[4]: boost.overloaded_function. WTF implementation is ugly?!
От: niXman Ниоткуда https://github.com/niXman
Дата: 14.09.13 10:40
Оценка:
таки получил препроцессированный код:
namespace overloaded_function_detail {

template<typename F>
class functor_type {
    typedef __typeof__(boost::type_of::ensure_obj(&F::operator())) call_ptr;
public:
    typedef typename boost::function_types::function_type<
        typename boost::mpl::push_front<
            typename boost::mpl::pop_front<
                typename boost::function_types::parameter_types<
                    call_ptr>::type
                >::type
            ,typename boost::function_types::result_type<call_ptr>::type
        >::type
    >::type type;
};

template<typename F>
struct functor_type< boost::function<F> > {
    typedef F type;
};

template<typename F>
struct function_type {
    typedef typename boost::mpl::if_<
         boost::function_types::is_function<F>
        ,boost::mpl::identity<F>
        ,typename boost::mpl::if_<
             boost::function_types::is_function_pointer<F>
            ,boost::remove_pointer<F>
            ,typename boost::mpl::if_<
                 boost::function_types::is_function_reference<F>
                ,boost::remove_reference<F>
                ,functor_type<F>
            >::type
        >::type
    >::type::type type;
};

}

namespace boost {

template<typename F0 , typename F1 , typename F2 = void , typename F3 = void , typename F4 = void>
class overloaded_function
    :public boost::overloaded_function_detail::base< F0 >
    ,public boost::overloaded_function_detail::base< F1 >
    ,public boost::overloaded_function_detail::base< F2 >
    ,public boost::overloaded_function_detail::base< F3 >
    ,public boost::overloaded_function_detail::base< F4 >

{
public:
    template<typename G0 , typename G1 , typename G2 , typename G3 , typename G4>
     inline overloaded_function(G0 g0 , G1 g1 , G2 g2 , G3 g3 , G4 g4)
        :boost::overloaded_function_detail::base< F0 >(g0)
        ,boost::overloaded_function_detail::base< F1 >(g1)
        ,boost::overloaded_function_detail::base< F2 >(g2)
        ,boost::overloaded_function_detail::base< F3 >(g3)
        ,boost::overloaded_function_detail::base< F4 >(g4)
    {}
    
    using boost::overloaded_function_detail::base< F0 >::operator();
    using boost::overloaded_function_detail::base< F1 >::operator();
    using boost::overloaded_function_detail::base< F2 >::operator();
    using boost::overloaded_function_detail::base< F3 >::operator();
    using boost::overloaded_function_detail::base< F4 >::operator();
};

template<typename F0 , typename F1 , typename F2 , typename F3 , typename F4>
overloaded_function<
     typename boost::overloaded_function_detail::function_type< F0 >::type
    ,typename boost::overloaded_function_detail::function_type< F1 >::type
    ,typename boost::overloaded_function_detail::function_type< F2 >::type
    ,typename boost::overloaded_function_detail::function_type< F3 >::type
    ,typename boost::overloaded_function_detail::function_type< F4 >::type
> make_overloaded_function(F0 f0 , F1 f1 , F2 f2 , F3 f3 , F4 f4) {
    return overloaded_function<
         typename boost::overloaded_function_detail::function_type< F0 >::type
        ,typename boost::overloaded_function_detail::function_type< F1 >::type
        ,typename boost::overloaded_function_detail::function_type< F2 >::type
        ,typename boost::overloaded_function_detail::function_type< F3 >::type
        ,typename boost::overloaded_function_detail::function_type< F4 >::type
    >( f0 , f1 , f2 , f3 , f4);
}

}

namespace boost {

template<typename F0 , typename F1 , typename F2 , typename F3>
class overloaded_function<F0 , F1 , F2 , F3>
    :public boost::overloaded_function_detail::base< F0 >
    ,public boost::overloaded_function_detail::base< F1 >
    ,public boost::overloaded_function_detail::base< F2 >
    ,public boost::overloaded_function_detail::base< F3 >

{
public:
    template<typename G0 , typename G1 , typename G2 , typename G3>
    inline overloaded_function(G0 g0 , G1 g1 , G2 g2 , G3 g3)
        :boost::overloaded_function_detail::base< F0 >(g0)
        ,boost::overloaded_function_detail::base< F1 >(g1)
        ,boost::overloaded_function_detail::base< F2 >(g2)
        ,boost::overloaded_function_detail::base< F3 >(g3)
    {}
    
    using boost::overloaded_function_detail::base< F0 >::operator();
    using boost::overloaded_function_detail::base< F1 >::operator();
    using boost::overloaded_function_detail::base< F2 >::operator();
    using boost::overloaded_function_detail::base< F3 >::operator();
};

template<typename F0 , typename F1 , typename F2 , typename F3>
overloaded_function<
     typename boost::overloaded_function_detail::function_type< F0 >::type
    ,typename boost::overloaded_function_detail::function_type< F1 >::type
    ,typename boost::overloaded_function_detail::function_type< F2 >::type
    ,typename boost::overloaded_function_detail::function_type< F3 >::type
>
make_overloaded_function(F0 f0 , F1 f1 , F2 f2 , F3 f3) {
    return overloaded_function<
         typename boost::overloaded_function_detail::function_type< F0 >::type
        ,typename boost::overloaded_function_detail::function_type< F1 >::type
        ,typename boost::overloaded_function_detail::function_type< F2 >::type
        ,typename boost::overloaded_function_detail::function_type< F3 >::type
    >( f0 , f1 , f2 , f3);
}

}

namespace boost {

template<typename F0 , typename F1 , typename F2>
class overloaded_function <F0 , F1 , F2>
    :public boost::overloaded_function_detail::base< F0 >
    ,public boost::overloaded_function_detail::base< F1 >
    ,public boost::overloaded_function_detail::base< F2 >

{
public:
    template<typename G0 , typename G1 , typename G2>
    inline overloaded_function(G0 g0 , G1 g1 , G2 g2)
        :boost::overloaded_function_detail::base< F0 >(g0)
        ,boost::overloaded_function_detail::base< F1 >(g1)
        ,boost::overloaded_function_detail::base< F2 >(g2)
    {}
    
    using boost::overloaded_function_detail::base< F0 >::operator();
    using boost::overloaded_function_detail::base< F1 >::operator();
    using boost::overloaded_function_detail::base< F2 >::operator();
};

template<typename F0 , typename F1 , typename F2>
overloaded_function<
     typename boost::overloaded_function_detail::function_type< F0 >::type
     ,typename boost::overloaded_function_detail::function_type< F1 >::type
     ,typename boost::overloaded_function_detail::function_type< F2 >::type
>
make_overloaded_function(F0 f0 , F1 f1 , F2 f2) {
    return overloaded_function<
         typename boost::overloaded_function_detail::function_type< F0 >::type
        ,typename boost::overloaded_function_detail::function_type< F1 >::type
        ,typename boost::overloaded_function_detail::function_type< F2 >::type
    >( f0 , f1 , f2);
}

}

namespace boost {

template<typename F0 , typename F1>
class overloaded_function<F0 , F1>
    :public boost::overloaded_function_detail::base< F0 >
    ,public boost::overloaded_function_detail::base< F1 >
{
public:
    template<typename G0 , typename G1>
    inline overloaded_function(G0 g0 , G1 g1)
        :boost::overloaded_function_detail::base< F0 >(g0)
        ,boost::overloaded_function_detail::base< F1 >(g1)
    {}
    
    using boost::overloaded_function_detail::base< F0 >::operator();
    using boost::overloaded_function_detail::base< F1 >::operator();
};

template<typename F0 , typename F1>
overloaded_function<
     typename boost::overloaded_function_detail::function_type< F0 >::type
     ,typename boost::overloaded_function_detail::function_type< F1 >::type
>
make_overloaded_function(F0 f0 , F1 f1) {
    return overloaded_function<
         typename boost::overloaded_function_detail::function_type< F0 >::type
        ,typename boost::overloaded_function_detail::function_type< F1 >::type
    >( f0 , f1);
}

}

int add(int a, int b) { return a+b; }

int main() {
 auto func = boost::make_overloaded_function(add);
 return func(2, 2);
}
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[4]: boost.overloaded_function. WTF implementation is ugly?!
От: niXman Ниоткуда https://github.com/niXman
Дата: 14.09.13 10:44
Оценка: :)
Здравствуйте, jazzer, Вы писали:

J>Понимаешь, относительно буста есть две конфликтующих хотелки.

J>С одной стороны, постоянно раздаются вопли, что буст слишком большой и невозможно взять из него только одну библиотеку, так как она потянет за собой еще добрый десяток вроде бы не относящихся к делу.
слышал о таком. но, как мне кажется, это всего лишь отговорки, за которыми скрывается откровенное с++ невежество...

по правде сказать, список рассылки буста читаю уже более двух лет, и ни разу не видел такого, чтоб где-то говорилось о том, что библиотеки входящие в состав буста, должны стараться не зависеть от буста... думаю, это как минимум было бы странно %)
это все равно что в Qt, в QtGui, запретить использовать QtCore %)
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[5]: boost.overloaded_function. WTF implementation is ugly?!
От: jazzer Россия Skype: enerjazzer
Дата: 14.09.13 10:55
Оценка:
Здравствуйте, niXman, Вы писали:

X>Здравствуйте, jazzer, Вы писали:


J>>Понимаешь, относительно буста есть две конфликтующих хотелки.

J>>С одной стороны, постоянно раздаются вопли, что буст слишком большой и невозможно взять из него только одну библиотеку, так как она потянет за собой еще добрый десяток вроде бы не относящихся к делу.
X>слышал о таком. но, как мне кажется, это всего лишь отговорки, за которыми скрывается откровенное с++ невежество...

При чем тут невежество? Ведь действительно надо будет тянуть весь mpl (в сымсле директории с толпой файлов внутри), даже если ты заюзал всего лишь какой-нть mpl::int_...

X>по правде сказать, список рассылки буста читаю уже более двух лет, и ни разу не видел такого, чтоб где-то говорилось о том, что библиотеки входящие в состав буста, должны стараться не зависеть от буста... думаю, это как минимум было бы странно %)

X>это все равно что в Qt, в QtGui, запретить использовать QtCore %)

Хм. Я это там вижу регулярно. На review частенько библиотеки ругают, если они используют что-нть тяжелое типа mpl или fusion. Собственно, весь effort насчет modular boost — тоже ведь не на пустом месте и делается лидерами буста...

Но я свое мнение уже высказал — я это не очень понимаю. Общий когерентный (т.е. оттестированный) пакет для меня гораздо удобнее.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: boost.overloaded_function. WTF implementation is ugly?!
От: Abyx Россия  
Дата: 14.09.13 11:08
Оценка: +3 -1
Здравствуйте, niXman, Вы писали:

X>найдя немного свободного времени, я зарукоблудил такое.

открой список компиляторов которые поддерживает буст, и нарукоблудь так чтобы все поддерживались.
в т.ч. компиляторы типа Visual C++ 7.0 и GCC 3.2, которые еще поддерживались когда делали overloaded_function.

X>я ожидал там увидеть реализацию на основе fusion::map и К`о.

а потом когда напишешь свою реализацию на Boost.Fusion, сделай реализацию без него и сравни время компиляции.

а потом запости результат сюда, и мы сделаем ревью и устроим голосование, как это делается в бусте.
так несколько итераций, мы твою либу зааппрувим, и после этого ты сможешь говорить про "откровенное с++ невежество" и прочие смешные слова.
In Zen We Trust
Re[6]: boost.overloaded_function. WTF implementation is ugly?!
От: niXman Ниоткуда https://github.com/niXman
Дата: 14.09.13 11:21
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Ведь действительно надо будет тянуть весь mpl (в сымсле директории с толпой файлов внутри), даже если ты заюзал всего лишь какой-нть mpl::int_...

зачем вообще что-то выделать/отделять? хидеры ведь не поставляют с конечным приложением.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[2]: boost.overloaded_function. WTF implementation is ugly?!
От: niXman Ниоткуда https://github.com/niXman
Дата: 14.09.13 11:37
Оценка: :)
Здравствуйте, Abyx, Вы писали:

A>компиляторы типа Visual C++ 7.0 и GCC 3.2, которые еще поддерживались когда делали overloaded_function.

хочется думать, что ты хоть иногда пользуешься мозгом, но факты говорят об обратном.
тыц

Version 1.50.0
June 28th, 2012 12:48 GMT

New Libraries
— Functional/OverloadedFunction: Overload different functions into a single function object, from Lorenzo Caminiti.


проходи мимо, пожалуйста.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[3]: boost.overloaded_function. WTF implementation is ugly?!
От: Abyx Россия  
Дата: 14.09.13 12:45
Оценка: -1
Здравствуйте, niXman, Вы писали:

A>>компиляторы типа Visual C++ 7.0 и GCC 3.2, которые еще поддерживались когда делали overloaded_function.

X>хочется думать, что ты хоть иногда пользуешься мозгом, но факты говорят об обратном.
X>тыц
X>

X>Version 1.50.0
X>June 28th, 2012 12:48 GMT

X>New Libraries
X> — Functional/OverloadedFunction: Overload different functions into a single function object, from Lorenzo Caminiti.


да-да, 28 июня 12го.
то-то я смотрю 5 августа 13го вывесили новость что в следующем релизе собираются убрать поддержку старых компиляторов.

но ты с темы-то не соскакивай, ты в своем чудо-коде сделай поддержку хотя бы msvc-8.0 (2005), а то авторы именно его юзали для тестирования, а ты их так вот говном полил.

X>проходи мимо, пожалуйста.

не ходи на форум — проблема решена.
In Zen We Trust
Re[7]: boost.overloaded_function. WTF implementation is ugly?!
От: Abyx Россия  
Дата: 14.09.13 12:49
Оценка: +2 -1
Здравствуйте, niXman, Вы писали:

J>>Ведь действительно надо будет тянуть весь mpl (в сымсле директории с толпой файлов внутри), даже если ты заюзал всего лишь какой-нть mpl::int_...

X>зачем вообще что-то выделать/отделять? хидеры ведь не поставляют с конечным приложением.

внезапно да, поставляют, а иногда копируют весь буст в свой репозиторий VCS.
Q&A типа "Q: мне запрещают юзать другие либы, а я хочу boost.xxx. A: просто скопируй boost/xxx/ в свой проект" — море пруди.
добро пожаловать в реальный мир!
In Zen We Trust
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.