Use std::bind if available

pull/2/head
Stelios Bounanos 2008-01-02 20:42:16 +00:00
rodzic d3849ae877
commit 0dc1e2357e
7 zmienionych plików z 90 dodań i 117 usunięć

Wyświetl plik

@ -1,6 +1,8 @@
Change Log:
2.08 1) Use PortAudio's C API; the C++ bindings are no longer required
2) Boost is no longer required when std::(tr1::)bind is available, as is
the case with g++ >= 4.0
2.07 1) bug fix for mode changes via SysV interface (pskmail / flarq)
2) bug fix for modem configuration post quick change from status

Wyświetl plik

@ -3,10 +3,12 @@ Installation Instructions for fldigi
To compile fldigi you will need:
* version 1.1.x of the Fast Light Tool Kit (FLTK), with its
development libraries and headers, and
* A recent C++ compiler. The GNU C++ compilers in the 4.x series are
known to work. Building with g++ 3.x requires the development files
for the Boost C++ library.
* the development files for the Boost C++ library.
* Version 1.1.x of the Fast Light Tool Kit (FLTK), with its
development libraries and headers.
You should also install the libraries and headers for PortAudio, the
Portable audio I/O library. It is possible, but not recommended, to

Wyświetl plik

@ -110,11 +110,43 @@ fi
###########################
# Boost
# bind
###########################
AX_BOOST_BASE(1.32.0)
if test "x$want_boost" = "xno"; then
AC_MSG_ERROR([Boost is required])
# Look for a working std::bind or std::tr1::bind. If neither is present
# we will need Boost >= 1.32.0, which provides boost::bind.
AC_LANG_PUSH(C++)
AC_MSG_CHECKING([for std::bind in <functional>])
AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([[#include <functional>
void f(void) { }]],
[[std::bind(f)();]])],
[ac_cv_std_bind=yes], [ac_cv_std_bind=no] )
AC_MSG_RESULT([$ac_cv_std_bind])
if test "x$ac_cv_std_bind" = "xyes"; then
AC_DEFINE(HAVE_STD_BIND, 1, [Define to 1 if we have std::bind in <functional>])
else
AC_DEFINE(HAVE_STD_BIND, 0, [Define to 1 if we have std::bind in <functional>])
fi
if test "x$ac_cv_std_bind" = "xno"; then
AC_MSG_CHECKING([for std::tr1::bind in <tr1/functional>])
AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([[#include <tr1/functional>
void f(void) { }]],
[[std::tr1::bind(f)();]])],
[ac_cv_std_tr1_bind=yes], [ac_cv_std_tr1_bind=no] )
AC_MSG_RESULT([$ac_cv_std_tr1_bind])
if test "x$ac_cv_std_tr1_bind" = "xyes"; then
AC_DEFINE(HAVE_STD_TR1_BIND, 1, [Define to 1 if we have std::tr1::bind in <tr1/functional>])
else
AC_DEFINE(HAVE_STD_TR1_BIND, 0, [Define to 1 if we have std::tr1::bind in <tr1/functional>])
fi
fi
AC_LANG_POP(C++)
if test "x$ac_cv_std_bind" = "xno" && test "x$ac_cv_std_tr1_bind" = "xno"; then
AX_BOOST_BASE(1.32.0)
if test "x$want_boost" = "xno"; then
AC_MSG_ERROR([Boost is required])
fi
fi
###########################
@ -178,22 +210,22 @@ AC_ARG_WITH([sndfile],
esac],
[ac_cv_want_sndfile=check])
if test "x$ac_cv_want_sndfile" = "xno"; then
AC_DEFINE(USE_SNDFILE, 0, [Set to 1 if we are using sndfile, 0 otherwise])
AC_DEFINE(USE_SNDFILE, 0, [Define to 1 if we are using sndfile])
ac_cv_sndfile=no
else
PKG_CHECK_EXISTS(sndfile >= 1.0.10, ac_cv_sndfile=yes, ac_cv_sndfile=no)
if test "x$ac_cv_want_sndfile" = "xcheck"; then
PKG_CHECK_MODULES(SNDFILE, sndfile >= 1.0.10, [:], [:])
if test "x$ac_cv_sndfile" = "xyes"; then
AC_DEFINE(USE_SNDFILE, 1, [Set to 1 if we are using sndfile, 0 otherwise])
AC_DEFINE(USE_SNDFILE, 1, [Define to 1 if we are using sndfile])
else
AC_DEFINE(USE_SNDFILE, 0, [Set to 1 if we are using sndfile, 0 otherwise])
AC_DEFINE(USE_SNDFILE, 0, [Define to 1 if we are using sndfile])
fi
else # $ac_cv_want_sndfile is yes
if test "x$ac_cv_sndfile" = "xno"; then
AC_MSG_NOTICE([--with-sndfile was given, but test for sndfile failed])
else
AC_DEFINE(USE_SNDFILE, 1, [Set to 1 if we are using sndfile, 0 otherwise])
AC_DEFINE(USE_SNDFILE, 1, [Define to 1 if we are using sndfile])
fi
PKG_CHECK_MODULES(SNDFILE, sndfile >= 1.0.10) # for the error message
fi
@ -216,13 +248,13 @@ AC_ARG_WITH([portaudio],
if test "x$ac_cv_want_portaudio" = "xyes"; then
PKG_CHECK_EXISTS(portaudio-2.0 >= 19, ac_cv_portaudio=yes, ac_cv_portaudio=no)
if test "x$ac_cv_portaudio" = "xyes"; then
AC_DEFINE(USE_PORTAUDIO, 1, [Set to 1 if we are using PortAudio, 0 otherwise])
AC_DEFINE(USE_PORTAUDIO, 1, [Define to 1 if we are using PortAudio])
else
AC_MSG_NOTICE([portaudio test failed (use --without-portaudio to disable)])
fi
PKG_CHECK_MODULES(PORTAUDIO, portaudio-2.0 >= 19)
else
AC_DEFINE(USE_PORTAUDIO, 0, [Set to 1 if we are using PortAudio, 0 otherwise])
AC_DEFINE(USE_PORTAUDIO, 0, [Define to 1 if we are using PortAudio])
ac_cv_portaudio=no
fi
AC_SUBST([PORTAUDIO_CFLAGS])
@ -248,15 +280,15 @@ else
if test "x$ac_cv_want_hamlib" = "xcheck"; then
PKG_CHECK_MODULES(HAMLIB, hamlib >= 1.2.0, [:], [:])
if test "x$ac_cv_hamlib" = "xyes"; then
AC_DEFINE(USE_HAMLIB, 1, [Set to 1 if we are using hamlib, 0 otherwise])
AC_DEFINE(USE_HAMLIB, 1, [Define to 1 if we are using hamlib])
else
AC_DEFINE(USE_HAMLIB, 0, [Set to 1 if we are using hamlib, 0 otherwise])
AC_DEFINE(USE_HAMLIB, 0, [Define to 1 if we are using hamlib])
fi
else # $ac_cv_want_hamlib is yes
if test "x$ac_cv_hamlib" = "xno"; then
AC_MSG_NOTICE([--with-hamlib was given, but test for hamlib failed])
else
AC_DEFINE(USE_HAMLIB, 1, [Set to 1 if we are using hamlib, 0 otherwise])
AC_DEFINE(USE_HAMLIB, 1, [Define to 1 if we are using hamlib])
fi
PKG_CHECK_MODULES(HAMLIB, hamlib >= 1.2.0) # for the error message
fi

Wyświetl plik

@ -36,7 +36,7 @@
AC_DEFUN([AX_BOOST_BASE],
[
AC_ARG_WITH([boost],
AS_HELP_STRING([--with-boost=DIR], [specify the root directory for boost]),
AS_HELP_STRING([--with-boost=DIR], [specify the root directory for boost @<:@autodetect@:>@]),
[
if test "$withval" = "no"; then
want_boost="no"

Wyświetl plik

@ -7,7 +7,7 @@ AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/include -I$(srcdir)/irrxml @BOOST_CPPFLAGS
AM_CXXFLAGS = @FLTK_CFLAGS@ @PORTAUDIO_CFLAGS@ @SNDFILE_CFLAGS@ \
@SAMPLERATE_CFLAGS@ @HAMLIB_CFLAGS@ \
-pipe -Wall -O2 -ffast-math -fno-rtti -fexceptions -finline-functions
-pipe -Wall -O2 -ffast-math -fexceptions -finline-functions
AM_CFLAGS = $(AM_CXXFLAGS)
LDADD = @BOOST_LDFLAGS@ @FLTK_LIBS@ @PORTAUDIO_LIBS@ @SNDFILE_LIBS@ \

Wyświetl plik

@ -1202,7 +1202,7 @@ void put_Bandwidth(int bandwidth)
void display_metric(double metric)
{
FL_LOCK_D();
QUEUE(CMP_CB(&Fl_Progress::value, pgrsSquelch, metric)); //pgrsSquelch->value(metric);
QUEUE(CMP_CB(static_cast<void (Fl_Progress::*)(float)>(&Fl_Progress::value), pgrsSquelch, metric)); //pgrsSquelch->value(metric);
FL_UNLOCK_D();
FL_AWAKE_D();
}
@ -1213,8 +1213,8 @@ void put_cwRcvWPM(double wpm)
int L = progdefaults.CWlowerlimit;
double dWPM = 100.0*(wpm - L)/(U - L);
FL_LOCK_D();
QUEUE(CMP_CB(&Fl_Progress::value, prgsCWrcvWPM, dWPM)); //prgsCWrcvWPM->value(dWPM);
QUEUE(CMP_CB(&Fl_Value_Output::value, valCWrcvWPM, (int)wpm)); //valCWrcvWPM->value((int)wpm);
QUEUE(CMP_CB(static_cast<void (Fl_Progress::*)(float)>(&Fl_Progress::value), prgsCWrcvWPM, dWPM)); //prgsCWrcvWPM->value(dWPM);
QUEUE(CMP_CB(static_cast<int (Fl_Value_Output::*)(double)>(&Fl_Value_Output::value), valCWrcvWPM, (int)wpm)); //valCWrcvWPM->value((int)wpm);
FL_UNLOCK_D();
FL_AWAKE_D();
}
@ -1295,7 +1295,7 @@ void put_sec_char( char chr )
if (strSecText.length() > 60)
strSecText.erase(0,1);
FL_LOCK_D();
QUEUE(CMP_CB(&Fl_Box::label, StatusBar, strSecText.c_str())); //StatusBar->label(strSecText.c_str());
QUEUE(CMP_CB(static_cast<void (Fl_Box::*)(const char *)>(&Fl_Box::label), StatusBar, strSecText.c_str())); //StatusBar->label(strSecText.c_str());
FL_UNLOCK_D();
FL_AWAKE_D();
}
@ -1313,7 +1313,7 @@ void put_status(const char *msg, double timeout)
m[sizeof(m) - 1] = '\0';
FL_LOCK_D();
QUEUE(CMP_CB(&Fl_Box::label, StatusBar, m)); // StatusBar->label(m);
QUEUE(CMP_CB(static_cast<void (Fl_Box::*)(const char *)>(&Fl_Box::label), StatusBar, m)); // StatusBar->label(m);
// While it is safe to call to use Fl::add_timeout without qrunner
// regardless of our caller's context, queuing ensures that clear_status_cb
// really gets called at least ``timeout'' seconds after the label is set.
@ -1332,7 +1332,7 @@ void put_Status2(const char *msg)
m[sizeof(m) - 1] = '\0';
FL_LOCK_D();
QUEUE(CMP_CB(&Fl_Box::label, Status2, m)); //Status2->label(m);
QUEUE(CMP_CB(static_cast<void (Fl_Box::*)(const char *)>(&Fl_Box::label), Status2, m)); //Status2->label(m);
FL_UNLOCK_D();
FL_AWAKE_D();
}
@ -1344,7 +1344,7 @@ void put_Status1(const char *msg)
m[sizeof(m) - 1] = '\0';
FL_LOCK_D();
QUEUE(CMP_CB(&Fl_Box::label, Status1, m)); //Status1->label(m);
QUEUE(CMP_CB(static_cast<void (Fl_Box::*)(const char *)>(&Fl_Box::label), Status1, m)); //Status1->label(m);
FL_UNLOCK_D();
FL_AWAKE_D();
}
@ -1387,7 +1387,7 @@ void clear_StatusMessages()
void put_MODEstatus(trx_mode mode)
{
FL_LOCK_D();
QUEUE(CMP_CB(&Fl_Button::label, MODEstatus, mode_info[mode].sname)); //MODEstatus->label(mode_names[mode]);
QUEUE(CMP_CB(static_cast<void (Fl_Button::*)(const char *)>(&Fl_Button::label), MODEstatus, mode_info[mode].sname)); //MODEstatus->label(mode_names[mode]);
FL_UNLOCK_D();
FL_AWAKE_D();
}

Wyświetl plik

@ -24,14 +24,23 @@
#define QRUNNER_H_
#ifndef NDEBUG
# include <iostream>
# include <iostream>
#endif
#include <errno.h>
#include <stdexcept>
#include <cstring>
#include <boost/bind.hpp>
#include <boost/bind/protect.hpp>
#if HAVE_STD_BIND
# include <functional>
using std::bind;
#elif HAVE_STD_TR1_BIND
# include <tr1/functional>
using std::tr1::bind;
#else
# include <boost/bind.hpp>
using boost::bind;
#endif
#include "threads.h"
#include "qrunner/fqueue.h"
@ -48,66 +57,24 @@ private:
std::string msg;
};
struct signal_after
struct fsignal
{
typedef void result_type;
Fl_Mutex *m;
Fl_Cond *c;
signal_after(Fl_Mutex *m_, Fl_Cond *c_) : m(m_), c(c_) { }
template <typename F>
void operator()(const F& f) const
fsignal(Fl_Mutex *m_, Fl_Cond *c_) : m(m_), c(c_) { }
void operator()(void) const
{
f();
fl_lock(m);
fl_cond_signal(c);
fl_unlock(m);
}
};
struct deadline
{
struct timespec dl;
deadline(const struct timespec &dl_) : dl(dl_) { }
template <typename F>
void operator()(const F& f) const
{
struct timespec now;
if (clock_gettime(CLOCK_REALTIME, &now) == -1)
throw qexception(errno);
if (dl > now)
f();
#ifndef NDEBUG
else
std::cerr << "too late for event\n";
#endif
}
};
#ifndef NDEBUG
struct timer
{
struct timespec t;
timer(const struct timespec &t_) : t(t_) { }
template <typename F>
void operator()(const F& f) const
{
struct timespec now;
if (clock_gettime(CLOCK_REALTIME, &now) == -1)
throw qexception(errno);
struct timespec diff = now - t;
std::cout << "t: " << (double)diff.tv_sec + diff.tv_nsec/1e9 << '\n';
f();
}
};
#endif
struct nop
{
typedef void result_type;
void operator()(void) const { }
};
@ -146,13 +113,17 @@ public:
if (!attached)
return request(f, pri);
for (;;) {
if (request(f, pri))
break;
sched_yield();
}
Fl_Mutex m = PTHREAD_MUTEX_INITIALIZER;
Fl_Cond c = PTHREAD_COND_INITIALIZER;
fsignal s(&m, &c);
fl_lock(&m);
signal_after sa(&m, &c);
for (;;) {
if (request(boost::bind<void>(sa, f), pri))
if (request(s, pri))
break;
sched_yield();
}
@ -162,30 +133,6 @@ public:
return true;
}
template <typename F>
bool request_dl(const F &f, double dtime, size_t pri = 0)
{
struct timespec now, dl;
if (clock_gettime(CLOCK_REALTIME, &now) == -1)
throw qexception(errno);
dl = now + dtime;
deadline d(dl);
return request(boost::bind<void>(d, f), pri);
}
#ifndef NDEBUG
template <typename F>
bool request_time(const F &f, size_t pri = 0)
{
struct timespec now;
if (clock_gettime(CLOCK_REALTIME, &now) == -1)
throw qexception(errno);
timer t(now);
return request(boost::bind<void>(t, f), pri);
}
#endif
static void execute(int fd, void *arg);
void flush(void);
@ -211,29 +158,19 @@ extern qrunner *cbq[NUM_QRUNNER_THREADS];
#define QUEUE_ASYNC(...) \
do { \
if (GET_THREAD_ID() != FLMAIN_TID) \
cbq[GET_THREAD_ID()]->request(boost::bind(__VA_ARGS__)); \
cbq[GET_THREAD_ID()]->request(bind(__VA_ARGS__)); \
else \
boost::bind(__VA_ARGS__)(); \
bind(__VA_ARGS__)(); \
} while (0)
#define QUEUE_SYNC(...) \
do { \
if (GET_THREAD_ID() != FLMAIN_TID) \
cbq[GET_THREAD_ID()]->request_sync(boost::protect(boost::bind(__VA_ARGS__))); \
cbq[GET_THREAD_ID()]->request_sync(bind(__VA_ARGS__)); \
else \
boost::bind(__VA_ARGS__)(); \
bind(__VA_ARGS__)(); \
} while (0)
#define QUEUE_DL(d_, ...) \
do { \
if (GET_THREAD_ID() != FLMAIN_TID) \
cbq[GET_THREAD_ID()]->request_dl(boost::protect(boost::bind(__VA_ARGS__)), d_); \
else \
boost::bind(__VA_ARGS__)(); \
} while (0)
#define QUEUE_FLUSH() \
do { \
if (GET_THREAD_ID() != FLMAIN_TID) \