Execution guard
От: denisko http://sdeniskos.blogspot.com/
Дата: 11.11.09 14:33
Оценка: :))) :)
Народ а есть где нибудь в недрах буста (или не буста) класс, который принимает на вход класс и если выполнены некоторые условия, вызывает у него определенную функцию. Самому написать не проблема, но лень.
З.ы. не поверите в гугле таки забанили.
<Подпись удалена модератором>
Re: Execution guard
От: zaufi Земля  
Дата: 11.11.09 16:24
Оценка: :))
Здравствуйте, denisko, Вы писали:

D>Народ а есть где нибудь в недрах буста (или не буста) класс, который принимает на вход класс и если выполнены некоторые условия, вызывает у него определенную функцию. Самому написать не проблема, но лень.

D>З.ы. не поверите в гугле таки забанили.

ты слишком специализированные вопросы задаешь... суда по оценкам народ просто растерялся не найдя что ответить %)
Re: Execution guard
От: Tilir Россия http://tilir.livejournal.com
Дата: 11.11.09 16:43
Оценка:
Здравствуйте, denisko, Вы писали:

D>Народ а есть где нибудь в недрах буста (или не буста) класс, который принимает на вход класс и если выполнены некоторые условия, вызывает у него определенную функцию. Самому написать не проблема, но лень.

D>З.ы. не поверите в гугле таки забанили.

А чем не устраивает решение на макросе:

#include <iostream>

#define INVOKEFUN_C(COND, CLASS, FUNC, ...) if (COND) CLASS::FUNC(__VA_ARGS__);
#define INVOKEFUN_O(COND, OBJ, FUNC, ...) if (COND) OBJ.FUNC(__VA_ARGS__);


class A {
public:
  static void sf(int x, int y){
    std::cout << "sf(" << x << ", " << y << ")" << std::endl;
  }
  
  void f(int x, int y){
    std::cout << "f(" << x << ", " << y << ")" << std::endl;
  }
};

int main(void){
  INVOKEFUN_C(true, A, sf, 1, 2);
  A a;
  INVOKEFUN_O(true, a, f, 3, 4);  
  getchar();
  return 0;
}


Ну и сверху классов уже навертеть можно

Только вот зачем это может быть нужно...
Re: Execution guard
От: Alexander G Украина  
Дата: 11.11.09 16:57
Оценка: 37 (2)
Здравствуйте, denisko, Вы писали:

D>Народ а есть где нибудь в недрах буста (или не буста) класс, который принимает на вход класс и если выполнены некоторые условия, вызывает у него определенную функцию. Самому написать не проблема, но лень.

D>З.ы. не поверите в гугле таки забанили.

Попробую угадать.

boost::lambda::if_then

http://www.boost.org/doc/libs/1_40_0/doc/html/lambda/le_in_details.html#lambda.lambda_expressions_for_control_structures
Русский военный корабль идёт ко дну!
Re[2]: Execution guard
От: denisko http://sdeniskos.blogspot.com/
Дата: 11.11.09 17:00
Оценка:
Здравствуйте, zaufi, Вы писали:

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


D>>Народ а есть где нибудь в недрах буста (или не буста) класс, который принимает на вход класс и если выполнены некоторые условия, вызывает у него определенную функцию. Самому написать не проблема, но лень.

D>>З.ы. не поверите в гугле таки забанили.

Z>ты слишком специализированные вопросы задаешь... суда по оценкам народ просто растерялся не найдя что ответить %)

Да просто все, у нас есть товарищь, который ОООЧЕНЬ любит писать так
 bool func(arg1,arg2....argN)
{
 if(isValid(arg1) && isValid(arg2) && ..........)
 {
   if(andNobodyWantsToThrowSomeShit(member1,memer2,member3))
   {
      if(bullShitCondition1(..))
      {
         if(bullShitCondition2(...))
         {
            if(!bullShitConditionN(...))
            {
               throw wowIfuckedYourGuidelinesException;
            }
            else
            {
               return arg1 != arg2
            }
         }
      }
   }
   return false;
 }

и гордится этим.
1) По ряду причин, мы не используем исключения (слишком много наследного кода, причем шаблонного, который не поддерживает исключения).


Хочется иметь что-нибудь типа такой структуры
struct ProxyCall
{
   template<typename CallerClass, typename CallerFunc, typename agr1.....typename argN>
   ProxyCall(CallerFunc, CallerClass* caller):
   m_caller(caller)
   {
      
   }
   bool operator()(arg1,arg2...argN)
   {
      if(isValid(m_caller) && m_caller->testMyArgs(arg1....argN))
      {
       return SAFE_CALL(CallerFunc,CallerClass,arg1,arg2,argN);
      }
      return false;
   }
};

где SAFE_CALL -- ловит все разумные исключения товарища, пишет в лог и выставляет код ошибки. Как писать понятно, но писать нудно -- надо кучу операторов скобочка для каждого аргумента, да и наверняка это где то реализовано, вот такую реализацию я и ищу.
<Подпись удалена модератором>
Re[2]: Execution guard
От: denisko http://sdeniskos.blogspot.com/
Дата: 11.11.09 17:02
Оценка:
Здравствуйте, Alexander G, Вы писали:

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


D>>Народ а есть где нибудь в недрах буста (или не буста) класс, который принимает на вход класс и если выполнены некоторые условия, вызывает у него определенную функцию. Самому написать не проблема, но лень.

D>>З.ы. не поверите в гугле таки забанили.

AG>Попробую угадать.


AG>boost::lambda::if_then


AG>http://www.boost.org/doc/libs/1_40_0/doc/html/lambda/le_in_details.html#lambda.lambda_expressions_for_control_structures

Вах ! Большое человеческое спасибо!
<Подпись удалена модератором>
Re[2]: Execution guard
От: denisko http://sdeniskos.blogspot.com/
Дата: 11.11.09 17:04
Оценка:
Здравствуйте, Tilir, Вы писали:
Ну так и была идея делать, только все равно это нудно.
Для изоляции от общества буйнопомешанного товарища.
<Подпись удалена модератором>
Re[3]: Execution guard
От: Кодт Россия  
Дата: 11.11.09 23:06
Оценка:
Здравствуйте, denisko, Вы писали:

D>Да просто все, у нас есть товарищь, который ОООЧЕНЬ любит писать так

D>
D> bool func(arg1,arg2....argN)
D>{
D> if(isValid(arg1) && isValid(arg2) && ..........)
D> {
D>   if(andNobodyWantsToThrowSomeShit(member1,memer2,member3))
D>   {
D>      if(bullShitCondition1(..))
D>      {
D>         if(bullShitCondition2(...))
D>         {
D>            if(!bullShitConditionN(...))
D>            {
D>               throw wowIfuckedYourGuidelinesException;
D>            }
D>            else
D>            {
D>               return arg1 != arg2
D>            }
D>         }
D>      }
D>   }
D>   return false;
D> }
D>

D>и гордится этим.

Методы социального рефакторинга не пробовали?
Или, например,
struct trap
{
  // любой правоассоциативный оператор с низким приоритетом
  template<class Exception> trap& operator <<= (Exception const& e)
  {
    handle_the_exception(e); // пишет в лог, взводит флаг, утилизирует объект (если надо)
    return *this;
  }

  // для возвращения
  template<class Return> operator Return() const { return Return(); }
};

#ifdef пожалеем_раздолбая
#define throw  trap() <<= /*исключение*/
#else
#define throw !!! по голове себе постучи !!!
#endif


D>1) По ряду причин, мы не используем исключения (слишком много наследного кода, причем шаблонного, который не поддерживает исключения).



D>Хочется иметь что-нибудь типа такой структуры

D>где SAFE_CALL -- ловит все разумные исключения товарища, пишет в лог и выставляет код ошибки. Как писать понятно, но писать нудно -- надо кучу операторов скобочка для каждого аргумента, да и наверняка это где то реализовано, вот такую реализацию я и ищу.

Чтобы самому не заниматься с многоарными функциями, а сосредоточиться только на сути — задействуй boost::bind

Что-нибудь в таком роде:
template<class F>
typename boost::result_type<F>::type
safecall(F f)
{
  try
  {
    return f();
  }
  catch(...)
  {
    rethrow_handle_and_absorb();
    return default_value();
  }
}

// обработчик исключений, вынесенный за пределы вызова проблемного кода
void rethrow_handle_and_absorb
{
  try { throw; } // переизлучаем... но мы должны быть уверены, что вызвали эту функцию из catch(...)
  catch(aaa) { .... }
  catch(bbb) { .... }
  catch(ccc) { .... }
  catch(...) { .... }
}

// универсальный результат - приводится ко всем типам на свете
struct default_value
{
  template<class T> operator T() const { return T(); }
};

// вызываем
.... safecall(boost::bind(foo,1,2,3,4,5)) .....

А если хочешь биндить этот safecall, то
// карринг параметров шаблона: возвращаемый тип R отдельно,
template<class R> struct safecaller
{
  typedef R result_type;
  // а принимаемый F - отдельно
  template<class F> R operator()(F f) const { return safecall(f); }
};

// используем...
bar( .....
     bind(
       safecaller<bool>(), // тип объекта и тип result_type для bind нужны сразу (он их замучается выводить)
       protect( // изолируем внутренний бинд от внешнего
         bind(foo,1,2,3,4,5)
       ) // то есть, внутрь safecall<bool>()(_) приедет не результат вызова foo(1,2,3,4,5), а сам бинд
     )
     .....
    );

void bar(...., F f, .....) // F изоморфен bool(), т.е., например, function<void()> или параметр шаблона
{ ..... f(); ..... } // здесь f() тождественно предыдущей форме safecall(bind(foo,1,2,3,4,5))
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.