[c++]посоветуйте обёртку для переменной чтобы мьютекс приклеивался

elenangel

хочу такую штуку, скорее всего шаблон, чтобы можно было написать для любой переменной

lockable<string> s;
...

s.lock;
s = "Hello, world";
s.find("Hello");
s.erase(5,1);
s.unlock;

lockable<MyClass*> test;
...
test->lock;
test->foo;
test->unlock;


lockable<int> counter;
...
counter.lock;
if(counter>2) counter = 0;
counter.unlock;

пока что я набросал шаблон, но у него есть 2 недостатка:
с указателями получается так:
lockable<Test*> p;
p.lock;
p->foo;
p.unlock;
что выглядит черезжопно.
и второе - оно не хочет объявляться от простых типов а-ля int, char, double etc - только от классов и указателей. В принципе можно написать специализацию для каждого простого типа, но не хочется для каждого случая дублировать код.
вот что у меня есть сейчас:

#ifndef LOCKABLETEMPLATE_H
#define LOCKABLETEMPLATE_H


#include "ThreadSync.h"

template<class Mutex = ThreadSync>
class Lockable
{
    Mutex mutex;
public:
    void lock
    {
     mutex.lock;
    }
    void unlock
    {
     mutex.unlock;
    }
};

template<class T, class Mutex = ThreadSync>
class lockable: public T, public Lockable<Mutex>
{
public:
    lockable<T,Mutex>:T
    {
    }

    lockable<T,Mutex>(const T &t):T(t)
    {
    }

    lockable<T,Mutex>(const lockable<T,Mutex> &t):TT)t)
    {
    }

    operator T
    {
     return static_cast<T &>(*this);
    }

    lockable<T, Mutex> &operator=(T& new_val)
    {
     T &t = static_cast<T &>(*this);
     if(t)
     {
     t = new_val;
     }
     return *this;
    }

    lockable<T, Mutex> & operator=(lockable<T, Mutex>& new_val)
    {
     if(&new_val != this)
     {
     (*this) = static_cast<T>(new_val);
     }
     return *this;
    }
};

template<class T, class Mutex>
class lockable<T*, Mutex>: public Lockable<Mutex>
{
    T* ptr;
public:
    lockable<T*, Mutex>:ptr(0)
    {
    }

    lockable<T*, Mutex>(T* t):ptr(t)
    {
    }

    lockable<T*, Mutex>(const lockable<T*, Mutex> &t):T(t.ptr)
    {
    }

    operator T*
    {
     return ptr;
    }

    lockable<T*, Mutex> &operator=(T* new_val)
    {
     ptr = new_val;
     return *this;
    }

    lockable<T*, Mutex> & operator=(lockable<T*, Mutex>& new_val)
    {
     if(&new_val != this)
     {
     ptr = new_val.ptr;
     }
     return *this;
    }

    T& operator*
    {
     return *ptr;
    }
    T* operator->
    {
     return ptr;
    }
    operator bool
    {
     return ptr != 0;
    }
    void makeNull
    {
     ptr = 0;
    }
};


#endif // LOCKABLETEMPLATE_H

Serab

что выглядит черезжопно.
нормально оно выглядит. Ты когда-нибудь со smart-pointer'ами работал? Там все так же. Это же у тебя методы шаблонного класса, а не того, куда оно там указывает. Хотя можешь, конечно (слабонервным не читать специализировать для указателей, унаследовать внутренний класс по схожей схеме и добавить метод lock туда, а operator-> пускай возвращает указатель на этот внутренний класс.

Serab

А с lockable<int> counter еще можно хотеть counter++, удачного метапрограммирования :smirk:

elenangel

блин, я про ++ еще не подумал.
к указателям кстати тоже оно может понадобиться
Оставить комментарий
Имя или ник:
Комментарий: