Make RefCount<> more sensible

the previous version of operator*() made no sense. E.g., it violated the invariant
(*ptr).foo <=> ptr->foo. The dereferencing operator now returns a reference to the pointed-to
object, rather than a pointer to it.

I also added a bool conversion operator, which can be used in testing the NULL-ness of the
pointer. Anyone wondering if that could be done in a simpler way is encouraged to read
<http://www.artima.com/cppsource/safebool.html>.

And, finally, I removed the mutable flag from the m_data member, since it does not need it.
This commit is contained in:
Pavel Labath 2011-05-01 16:47:53 +02:00
parent fa15400cc2
commit 4b47675441
12 changed files with 27 additions and 23 deletions

View file

@ -51,7 +51,7 @@ void CommandDialog::exec(const std::string &text){
if (cmd.get())
cmd->execute();
// post execute
if (*m_postcommand != 0)
if (m_postcommand != 0)
m_postcommand->execute();
}

View file

@ -44,7 +44,7 @@ M *addCommands(M *macro, const string &args, bool trusted) {
std::vector<std::string>::iterator it = cmds.begin(), it_end = cmds.end();
for (; it != it_end; ++it) {
cmd = CommandParser<bool>::instance().parse(*it, trusted);
if (*cmd)
if (cmd)
macro->add(cmd);
}
@ -91,13 +91,13 @@ Command<void> *IfCommand::parse(const std::string &command, const std::string &a
return 0;
cond = CommandParser<bool>::instance().parse(cmds[0], trusted);
if (*cond == 0)
if (cond == 0)
return 0;
t = CommandParser<void>::instance().parse(cmds[1], trusted);
if (cmds.size() >= 3)
f = CommandParser<void>::instance().parse(cmds[2], trusted);
if (*t == 0 && *f == 0)
if (t == 0 && f == 0)
return 0;
return new IfCommand(cond, t, f);

View file

@ -38,9 +38,9 @@ public:
m_cond(cond), m_t(t), m_f(f) { }
void execute() {
if (m_cond->execute()) {
if (*m_t) m_t->execute();
if (m_t) m_t->execute();
} else
if (*m_f) m_f->execute();
if (m_f) m_f->execute();
}
static Command<void> *parse(const std::string &cmd, const std::string &args,
bool trusted);

View file

@ -42,7 +42,7 @@ M *addCommands(M *macro, const std::string &args, bool trusted) {
std::list<std::string>::iterator it = cmds.begin(), it_end = cmds.end();
for (; it != it_end; ++it) {
cmd = CommandParser<void>::instance().parse(*it, trusted);
if (*cmd)
if (cmd)
macro->add(cmd);
}
}

View file

@ -55,7 +55,7 @@ void MultiButtonMenuItem::click(int button, int time, unsigned int mods) {
if (button <= 0 || button > static_cast<signed>(buttons()) || buttons() == 0)
return;
if (*m_button_exe[button - 1] != 0)
if (m_button_exe[button - 1] != 0)
m_button_exe[button - 1]->execute();
}

View file

@ -27,6 +27,8 @@ namespace FbTk {
/// holds a pointer with reference counting, similar to std:auto_ptr
template <typename Pointer>
class RefCount {
typedef Pointer* RefCount::*bool_type;
public:
RefCount();
explicit RefCount(Pointer *p);
@ -35,9 +37,11 @@ public:
~RefCount();
RefCount<Pointer> &operator = (const RefCount<Pointer> &copy);
RefCount<Pointer> &operator = (Pointer *p);
Pointer *operator * () const { return get(); }
Pointer &operator * () const { return *get(); }
Pointer *operator -> () const { return get(); }
Pointer *get() const { return m_data; }
/// conversion to "bool"
operator bool_type() const { return m_data ? &RefCount::m_data : 0; }
private:
/// increase reference count
@ -45,7 +49,7 @@ private:
/// decrease reference count
void decRefCount();
Pointer *m_data; ///< data holder
mutable unsigned int *m_refcount; ///< holds reference counting
unsigned int *m_refcount; ///< holds reference counting
};
// implementation

View file

@ -98,7 +98,7 @@ void Timer::start() {
gettimeofday(&m_start, 0);
// only add Timers that actually DO something
if ((! m_timing || m_interval != 0) && *m_handler) {
if ((! m_timing || m_interval != 0) && m_handler) {
m_timing = true;
addTimer(this); //add us to the list
}
@ -121,7 +121,7 @@ void Timer::makeEndTime(timeval &tm) const {
void Timer::fireTimeout() {
if (*m_handler)
if (m_handler)
m_handler->execute();
}
@ -273,7 +273,7 @@ Command<void> *DelayedCmd::parse(const std::string &command,
return 0;
RefCount<Command<void> > cmd(CommandParser<void>::instance().parse(cmd_str, trusted));
if (*cmd == 0)
if (cmd == 0)
return 0;
int delay = 200000;

View file

@ -487,7 +487,7 @@ bool Keys::addBinding(const string &linebuffer) {
first_new_key = new t_key(type, mod, key, context,
isdouble);
current_key = first_new_key;
} else if (*current_key->m_command) // already being used
} else if (current_key->m_command) // already being used
return false;
} else {
t_key *temp_key = new t_key(type, mod, key, context,
@ -511,7 +511,7 @@ bool Keys::addBinding(const string &linebuffer) {
if (str) // +1 to skip ':'
current_key->m_command = FbTk::CommandParser<void>::instance().parse(str + 1);
if (!str || *current_key->m_command == 0 || mod) {
if (!str || current_key->m_command == 0 || mod) {
delete first_new_key;
return false;
}
@ -572,7 +572,7 @@ bool Keys::doAction(int type, unsigned int mods, unsigned int key,
setKeyMode(next_key);
return true;
}
if (!temp_key || *temp_key->m_command == 0) {
if (!temp_key || temp_key->m_command == 0) {
if (type == KeyPress &&
!FbTk::KeyUtil::instance().keycodeToModmask(key)) {
// if we're in the middle of an emacs-style keychain, exit it

View file

@ -328,7 +328,7 @@ void translateMenuItem(FbTk::Parser &parse, ParseItem &pitem,
// we need to attach command to arguments so command parser can parse it
string line = str_key + " " + str_cmd;
FbTk::RefCount<FbTk::Command<void> > command(FbTk::CommandParser<void>::instance().parse(line));
if (*command != 0) {
if (command != 0) {
// special NLS default labels
if (str_label.empty()) {
if (str_key == "reconfig" || str_key == "reconfigure") {

View file

@ -584,8 +584,8 @@ Application* findMatchingPatterns(ClientPattern *pat, Remember::Patterns *patlis
for (; it != it_end; ++it) {
if (*it->first == *pat && is_group == it->second->is_grouped &&
transient == it->second->is_transient &&
((match_pat == 0 && *it->second->group_pattern == 0) ||
(match_pat && *match_pat == **it->second->group_pattern))) {
((match_pat == 0 && it->second->group_pattern == 0) ||
(match_pat && *match_pat == *it->second->group_pattern))) {
Application *ret = it->second;
@ -887,7 +887,7 @@ void Remember::save() {
grouped_apps.insert(&a);
// otherwise output this whole group
apps_file << "[group]";
if (*a.group_pattern)
if (a.group_pattern)
apps_file << " " << a.group_pattern->toString();
apps_file << endl;
@ -1366,7 +1366,7 @@ FluxboxWindow *Remember::findGroup(Application *app, BScreen &screen) {
for (; it != it_end; ++it) {
if (it->second == app && it->first->fbwindow() &&
&screen == &it->first->screen() &&
(!*app->group_pattern || app->group_pattern->match(*it->first)))
(!app->group_pattern || app->group_pattern->match(*it->first)))
return it->first->fbwindow();
}

View file

@ -92,7 +92,7 @@ ToolbarItem *ToolFactory::create(const std::string &name, const FbTk::FbWindow &
item = new ClockTool(parent, m_clock_theme, screen(), tbar.menu());
} else {
FbTk::RefCount<FbTk::Command<void> > cmd(FbTk::CommandParser<void>::instance().parse(name));
if (*cmd == 0) // we need a command
if (cmd == 0) // we need a command
return 0;
// TODO maybe direction of arrows should depend on toolbar layout ?

View file

@ -90,7 +90,7 @@ void WindowListCmd::execute() {
WindowCmd<void>::setWindow((*it)->fbwindow());
else if (typeid(**it) == typeid(WinClient))
WindowCmd<void>::setClient(dynamic_cast<WinClient *>(*it));
if (!*m_filter || m_filter->execute())
if (!m_filter || m_filter->execute())
m_cmd->execute();
}
WindowCmd<void>::setClient(old);