Is there are common pattern OR ready-to-use boost class for "cached calculation"/"cached getter"?
I mean something like this:
class Test{
public:
Value getValue() const;
protected:
Value calculateValue() const;//REALLY expensive operation.
mutable bool valueIsDirty;
mutable Value cachedValue;
}
Value Test::getValue() const{
if (valueIsDirty){
cachedValue = calculateValue();
valueIsDirty = false;
}
return cachedValue;
}
I can use std::pair<Value, bool> and turn getValue/calculateValue into macro, but this doesn't really help if value depends on other values (stored in other classes) and those values can also be cached.
Is there a ready-to-use solution for this kind of "pattern"? At the moment I handle such cached values manually, but this isn't "pretty".
Restrictions:
c++03 standard. Boost is allowed.
The Proxy design pattern can help with this.
A typical implementation will define a class ValuePtr that behaves just like an ordinary Value*, i.e. it has an overloaded operator-> and operator*. But instead of directly accessing the underlying Value object, these operators also contain the logic of deciding to load or recompute the actual value. This extra level of indirection will encapsulate the proxy logic.
If you need to count refences to other objects, maybe std::shared_ptr<Value> is useful to use as the underyling data type inside ValuePtr.
See this site for a code example. Boost.Flyweight might also help.
This is what I ended up using:
template<typename T, typename Owner> class CachedMemberValue{
public:
typedef T (Owner::*Callback)() const;
T get(){
if (dirty){
cachedValue = (owner->*calculateCallback)();
dirty = false;
}
return cachedValue;
}
const T& getRef(){
if (dirty){
cachedValue = (owner->*calculateCallback)();
dirty = false;
}
return cachedValue;
}
void markDirty(){
dirty = true;
}
CachedMemberValue(Owner* owner_, Callback calculateCallback_)
:owner(owner_), calculateCallback(calculateCallback_), dirty(true){
}
protected:
Owner *owner;
Callback calculateCallback;
bool dirty;
T cachedValue;
private:
CachedMemberValue(const CachedMemberValue<T, Owner>&){
}
CachedMemberValue<T, Owner>& operator=(const CachedMemberValue<T, Owner>&){
return *this;
}
};
usage:
class MyClass{
public:
int getMin() const{
return cachedMin.get();
}
void modifyValue() { /*... calculation/modification*/ cachedMin.markDirty();}
MyClass(): cachedMin(this, &MyClass::noncachedGetMin){}
private:
int noncachedGetMin() const{ /*expensive operation here*/ ... }
mutable CachedMemberValue<int, MyClass> cachedMin;
};
Related
I have the following class:
class Document
{
public:
Document():
// default values for members,
// ...
m_dirty{false}{}
// Accessor functions
template<class OutputStream>
Document& save(OutputStream stream)
{
// Write stuff to `stream`
// ...
m_dirty = false;
return *this;
}
bool dirty() const { return m_dirty; }
private:
Size2d m_canvas_size;
LayerStack m_layers;
LayerIndex m_current_layer;
std::vector<Palette> m_palettes;
PaletteIndex m_current_palette;
ColorIndex m_current_color;
std::vector<std::string> m_palette_names;
std::vector<std::string> m_layer_names;
bool m_dirty;
};
Should the class have public member functions for modifying an element of say m_palettes directly, like
Document& color(PaletteIndex, ColorIndex, Color)
, or is it more "correct", to only allow access to the entire vector, through a pair of API:s
std::vector<Palette> const& palettes();
Document& palettes(std::vector<Palette>&&);
The first option would be more efficient, since it would not require to create a temporary copy of the data member, but consistent use of this design would make the interface bloated. It would require "deep" getters and setters for every container in the class.
Notice the dirty flag. Thus, the following would break the abstraction:
std::vector<Palette>& palettes();
You might have Proxy to "propagate" dirty flag from Palette modification, something like:
template <typename T>
class DirtyProxy
{
T& data;
bool& dirty;
public:
DirtyProxy(T& data, bool& dirty) : data(data), dirty(dirty) {}
~DirtyProxy() { dirty = true;}
DirtyProxy(const DirtyProxy&) = delete;
T* operator ->() { return data; }
};
And then
DirtyProxy<Palette> palette(std::size_t i) { return {m_palettes.at(i), dirty}; }
I think the most robust way to solve it is to use a a callback. An issue with the proxy is that it would not handle the case where the the client code throws an exception (assuming strong exception guarantee). Testcase:
try
{
auto property_proxy = obj.getProperty();
// an exception is thrown here...
property_proxy->val = x; // Never updated
}
catch(...)
{}
assert(!obj.dirty());
will fail, because the dtor always sets the dirty flag. However with a callback
class Foo
{
public:
template<class F>
Foo& modifyInSitu(F&& f)
{
f(x);
m_dirty = true;
return *this
}
};
will only update m_dirty, when f(x) does not throw.
I have a class design similar to the following:
class MyClass {
public:
bool IsValid() const;
void MakeValid();
private:
bool CheckValidity(bool fix);
};
bool MyClass::IsValid() const {
// Check validity, but don't fix any problems found. Doesn't work.
return CheckValidity(false);
}
void MyClass::MakeValid() {
// Check validity and fix problems found.
CheckValidity(true);
}
IsValid should be const, because it doesn't make changes. MakeValid should be non-const, because it does make changes. They share the same implementation, CheckValidity, but because CheckValidity may or may not make changes, it can't be marked const.
What's the best way to handle this? The simplest approach is to just use const_cast, but casting away const feels a bit dirty:
bool MyClass::IsValid() const {
// Check validity, but don't fix any problems found.
return const_cast<MyClass*>(this)->CheckValidity(false);
}
Is this a legitimate use of const_cast? Is there a better approach?
I'm assuming your implementation looks similar to this:
bool CheckValidity(bool fix)
{
// Actually check validity.
bool isValid = ...;
if (!isValid && fix)
{
// Attempt to fix validity (and update isValid).
isValid = ...;
}
return isValid;
}
You really have two different functions shoved into one. One of the key indicators of this kind of entanglement is the boolean argument to the function... which smells because the caller cannot immediately discern whether to put true or false without referencing code/docs.
Split up the method:
bool CheckValidity() const
{
// Actually check validity.
bool isValid = ...;
return isValid;
}
void FixValidity()
{
// Attempt to fix validity.
// ...
}
And then your public methods can make the calls more appropriately.
bool IsValid() const
{
// No problem: const method calling const method
return CheckValidity();
}
void MakeValid()
{
if (!CheckValidity()) // No problem: non-const calling const
{
FixValidity(); // No problem: non-const calling non-const
}
}
Here is an approach that might be useful in some cases. It might be overkill for your particular situation.
Your CheckValidity function could be passed a handler object. The CheckValidity function would find what was not valid, and call an appropriate method of the handler object. You could have many different methods for different kinds of validity violations, and those methods could be passed enough information that the problem could be fixed if necessary. To implement IsValid, you just need to pass a handler which sets a flag indicating there was a problem. To implement MakeValid, you can pass a handler which actually fixes the problem. The const issue is addressed by having the fixing handler keep a non-const reference to the object.
Here is an example:
class MyClass {
public:
bool IsValid() const
{
bool flag = false;
CheckValidity(FlagProblems{flag});
return flag;
}
void MakeValid()
{
CheckValidity(FixProblems{*this});
}
private:
struct FlagProblems {
bool& flag;
void handleType1(arg1,arg2) const { flag = true; }
void handleType2(arg1,arg2,arg3) const { flag = true; }
.
.
.
};
struct FixProblems {
MyClass& object;
void handleType1(arg1,arg2) const { ... }
void handleType2(arg1,arg2,arg3) const { ... }
.
.
.
};
template <typename Handler>
bool CheckValidity(const Handler &handler) const
{
// for each possible problem:
// if it is a type-1 problem:
// handler.handleType1(arg1,arg2);
// if it is a type-2 problem:
// handler.handleType2(arg1,arg2,arg3);
// .
// .
// .
}
};
Using the template allows for maximum efficiency. Alternatively, using a base class with virtual functions for the handler might provide a smaller executable size.
If the ways in which the object can be invalid are simpler, then having CheckValidity return a struct containing the relevant information may be more straightforward.
You can use a template specialization to separate the parts that only have purpose on a non-const object.
Following is an implementation for a toy class. It has a single c-array member v with 10 ints, and, for our purposes, it is only valid when every single one of them equals to zero.
class ten_zeroes {
int v[10];
void fix(int pos) {v[pos] = 0;}
public:
ten_zeroes() { // construct as invalid object
for (int i=0;i<10;i++) {
v[i] = i;
}
}
};
See that I already made a function member that fixes an invalid position, and a nice constructor that initializes it as an invalid object(don't do that :D)
Since we are going to use templates, we need to move the implementation of the check/fix cycle outside of the class. In order for the relevant functions to be able to access v and the fix() method, we'll make them friends. Our code now looks like:
class ten_zeroes {
int v[10];
void fix(int pos) {v[pos] = 0;}
public:
ten_zeroes() { // construct as invalid object
for (int i=0;i<10;i++) {
v[i] = i;
}
}
template<typename T>
friend void fix(T& obj, int pos);
template<typename T>
friend bool check(T& obj);
};
check()'s implementation is straightforward:
// Check and maybe fix object
template<typename T>
bool check(T& obj){
bool result = true;
for(int i=0;i<10;i++) {
if (obj.v[i]) {
result = false;
fix(obj, i);
}
}
return result;
}
Now here is the tricky part. We want our fix() function to change behaviour based on constness. For that we'll need to specialize the template. For a non-const object, it will fix the position. For a const one, it will do nothing:
// For a regular object, fix the position
template<typename T>
void fix(T& obj, int pos) { obj.fix(pos);}
// For a const object, do nothing
template<typename T>
void fix(const T& obj, int pos) {}
Finally, we write our is_valid() and make_valid() methods, and here we have the full implementation:
#include <iostream>
class ten_zeroes {
int v[10];
void fix(int pos) {v[pos] = 0;}
public:
ten_zeroes() { // construct as invalid object
for (int i=0;i<10;i++) {
v[i] = i;
}
}
bool is_valid() const {return check(*this);} // since this is const, it will run check with a const ten_zeroes object
void make_valid() { check(*this);} // since this is non-const , it run check with a non-const ten_zeroes object
template<typename T>
friend void fix(T& obj, int pos);
template<typename T>
friend bool check(T& obj);
};
// For a regular object, fix the position
template<typename T>
void fix(T& obj, int pos) { obj.fix(pos);}
// For a const object, do nothing
template<typename T>
void fix(const T& obj, int pos) {}
// Check and maybe fix object
template<typename T>
bool check(T& obj){
bool result = true;
for(int i=0;i<10;i++) {
if (obj.v[i]) {
result = false;
fix(obj, i);
}
}
return result;
}
int main(){
ten_zeroes a;
std::cout << a.is_valid() << a.is_valid(); // twice to make sure the first one didn't make any changes
a.make_valid(); // fix the object
std::cout << a.is_valid() << std::endl; // check again
}
I hope you don't mind the main() function there. It will test our little toy, and output 001, as expected. Now any maintenance on this code will not have to deal with code duplication, what you probably was intending to avoid. I hope this was helpful.
Of course, if you intend to hide these implementation details from the final user, you should move them to an appropriate detail namespace. I'll leave that up to you :)
Ok, the question title is a bit hard to phrase. What I am trying to achieve is create a template class with get/set functions that can handle simple types and structures.
This is simple for types such as integers and char, etc... But when the template type 'T' is a struct then it gets harder.
For example, here is a template class, where I have omitted various parts of it (such as constructor, etc), but it shows the get/set function:
EDIT: Only this class is allowed to modify the data, so passing a reference outside is not allowed. The reason is that I want to do a mutex around the set/get. I will/have update the functions...
template <class T> class storage
{
private:
T m_var;
pthread_mutex_t m_mutex;
public:
void set(T value)
{
pthread_mutex_lock(&m_mutex);
m_var = value;
pthread_mutex_unlock(&m_mutex);
}
T get(void)
{
T tmp;
// Note: Can't return the value within the mutex otherwise we could get into a deadlock. So
// we have to first read the value into a temporary variable and then return that.
pthread_mutex_lock(&m_mutex);
tmp = m_var;
pthread_mutex_unlock(&m_mutex);
return tmp;
}
};
Then consider the following code:
struct shape_t
{
int numSides;
int x;
int y;
}
int main()
{
storage<int> intStore;
storage<shape_t> shapeStore;
// To set int value I can do:
intStore.set(2);
// To set shape_t value I can do:
shape_t tempShape;
tempShape.numSides = 2;
tempShape.x = 5;
tempShape.y = 4;
shapeStore.set(tempShape);
// To modify 'x' (and keep y and numSides the same) I have to do:
shape_t tempShape = shapeStore.get();
tempShape.x = 5;
shapeStore.set(tempShape);
}
What I want to be able to do, if its possible, is to set the members of shape_t individually via some means in the template class, something like:
shapeStore.set(T::numSides, 2);
shapeStore.set(T::x, 5);
shapeStore.set(T::y, 4);
And not have to use a temp var. Is this possible? how?
I looked at this answer, but it did not quite do what I wanted because it is for a specific structure type
Make your get() member return a reference:
T& get()
{
return m_var;
}
Then you could say
shapeStore.get().x = 42;
Note it is good practice to add a const overload:
const T& get() const
{
return m_var;
}
Also note that if your get and set methods really do nothing special, as in your example, you might consider making the data public and doing away with getters/setters:
template <class T> struct storage
{
T m_var;
};
Edit: If you want to allow synchronised changes to the member, an option is to have a method that takes a modifying function. The function is applied inside the class, in your case, protected by the mutex. For example,
template <class T> struct storage
{
storage() : m_var() {}
void do_stuff(std::function<void(T&)> f)
{
std::lock_guard<std::mutex> lock(m_mutex);
f(m_var);
}
private:
T m_var;
std::mutex_t m_mutex;
};
Then you can modify members in a synchronised manner:
storage<shape_t> shapeStore;
shapeStore.do_stuff([](shape_t& s)
{ s.x = 42;
s.y = 100; });
If you don't have C++11 you can pass a function instead:
void foo(shape_t& s) { s.x = 42; }
shapeStore.do_stuff(foo);
Your design is fairly workable for primitive types, but it requires you to replicate the entire interface of class types and quickly becomes unmanageable. Even in the case of primitive types, you might want to enable more complex atomic operations than simply get and set, e.g., increment or add or multiply. The key to simplifying the design is to realize that you don't actually want to interpose on every single operation the client code performs on the data object, you only need to interpose before and after the client code atomically performs a sequence of operations.
Anthony Williams wrote a great article in Doctor Dobb's Journal years ago about this exact problem using a design where the manager object provides a handle to the client code that the client uses to access the managed object. The manager interposes only on the handle creation and destruction allowing clients with a handle unfettered access to the managed object. (See the recent proposal for standardization for excruciating detail.)
You could apply the approach to your problem fairly easily. First, I'll replicate some parts of the C++11 threads library because they make it MUCH easier to write correct code in the presence of exceptions:
class mutex {
pthread_mutex_t m_mutex;
// Forbid copy/move
mutex(const mutex&); // C++11: = delete;
mutex& operator = (const mutex&); // C++11: = delete;
public:
mutex(pthread_mutex_) { pthread_mutex_init(&m_mutex, NULL); }
~mutex() { pthread_mutex_destroy(&m_mutex); }
void lock() { pthread_mutex_lock(&m_mutex); }
void unlock() { pthread_mutex_unlock(&m_mutex); }
bool try_lock() { return pthread_mutex_trylock(&m_mutex) == 0; }
};
class lock_guard {
mutex& mtx;
public:
lock_guard(mutex& mtx_) : mtx(mtx_) { mtx.lock(); }
~lock_guard() { mtx.unlock(); }
};
The class mutex wraps up a pthread_mutex_t concisely. It handles creation and destruction automatically, and saves our poor fingers some keystrokes. lock_guard is a handy RAII wrapper that automatically unlocks the mutex when it goes out of scope.
storage then becomes incredibly simple:
template <class> class handle;
template <class T> class storage
{
private:
T m_var;
mutex m_mutex;
public:
storage() : m_var() {}
storage(const T& var) : m_var(var) {}
friend class handle<T>;
};
It's simply a box with a T and a mutex inside. storage trusts the handle class to be friendly and allows it poke around its insides. It should be clear that storage does not directly provide any access to m_var, so the only way it could possibly be modified is via a handle.
handle is a bit more complex:
template <class T>
class handle {
T& m_data;
lock_guard m_lock;
public:
handle(storage<T>& s) : m_data(s.m_var), m_lock(s.m_mutex) {}
T& operator* () const {
return m_data;
}
T* operator -> () const {
return &m_data;
}
};
it keeps a reference to the data item and holds one of those handy automatic lock objects. The use of operator* and operator-> make handle objects behave like a pointer to T.
Since only way to access the object inside storage is through a handle, and a handle guarantees that the appropriate mutex is held during its lifetime, there's no way for client code to forget to lock the mutex, or to accidentally access the stored object without locking the mutex. It can't even forget to unlock the mutex, which is nice as well. Usage is simple (See it working live at Coliru):
storage<int> foo;
void example() {
{
handle<int> p(foo);
// We have exclusive access to the stored int.
*p = 42;
}
// other threads could access foo here.
{
handle<int> p(foo);
// We have exclusive access again.
*p *= 12;
// We can safely return with the mutex held,
// it will be unlocked for us in the handle destructor.
return ++*p;
}
}
You would code the program in the OP as:
struct shape_t
{
int numSides;
int x;
int y;
};
int main()
{
storage<int> intStore;
storage<shape_t> shapeStore;
// To set int value I can do:
*handle<int>(intStore) = 2;
{
// To set shape_t value I can do:
handle<shape_t> ptr(shapeStore);
ptr->numSides = 2;
ptr->x = 5;
ptr->y = 4;
}
// To modify 'x' (and keep y and numSides the same) I have to do:
handle<shape_t>(shapeStore)->x = 5;
}
I can propose you alternative solution.
When you need you can get special template class that allows managing containing object.
template < typename T >
class SafeContainer
{
public:
// Variadic template for constructor
template<typename ... ARGS>
SafeContainer(ARGS ...arguments)
: m_data(arguments ...)
{};
// RAII mutex
class Accessor
{
public:
// lock when created
Accessor(SafeContainer<T>* container)
:m_container(container)
{
m_container->m_mutex.lock();
}
// Unlock when destroyed
~Accessor()
{
m_container->m_mutex.unlock();
}
// Access methods
T* operator -> ()
{
return &m_container->m_data;
}
T& operator * ()
{
return m_container->data;
}
private:
SafeContainer<T> *m_container;
};
friend Accessor;
Accessor get()
{
return Accessor(this);
}
private:
T m_data;
// Should be using recursive mutex to avoid deadlocks
std::mutex m_mutex;
};
Example:
struct shape_t
{
int numSides;
int x;
int y;
};
int main()
{
SafeContainer<shape_t> shape;
auto shapeSafe = shape.get();
shapeSafe->numSides = 2;
shapeSafe->x = 2;
}
I have two classes
class PopulationMember
{
public:
void operationOnThisMember1();
void operationOnThisMember2();
...
private:
Population* populaltion_;
}
class Population
{
public:
void operationOnAllMembers1();
void operationOnAllMembers2();
...
void operationOnAllMembers100();
void sortAllMembersCriterium1();
void sortAllMembersCriterium2();
...
void sortAllMembersCriterium100();
private:
QVector<PopulationMember*> members_;
}
I would like to implement a SELECT-like functionality to my framework. That is be able to perform operations only on those members which share a certain combination of properties.
So far I have thought out two approaches:
Implement a method that would return a new Population object composed of Members that satisfy a certain condition.
Popuation Popuation::select(bool (predicate*) (PopulationMember*));
Add a
bool selected_;
flag to each PopulationMember.
If I do 1. There is no way to implement sorting of selected data and deletion. If I do 2. There is overhead with checking for selectedness and I would have to reimplement sorting and other algorithms to operate only on selected members.
Is there a third, better way?
The approach I would take is to expose an iterator interface to the entire collection. To implement some sort of selection I would then use iterator adapters, e.g. one taking a unary predicate, which provide a new view of the range. This way there is neither an impact on the stored object nor any overhead in creating a separate collection. If you look at Boost's iterator adapters you may already get pretty much what is needed.
I have never looked, but I expect it will be method 1. See the MySQL source code to confirm my expectation. :-)
This is a proposal based on something similar i had to do once, which is an extended form of your first approach.
The advantage is the usage of STL's concepts and the freedom to either implement many functors or few parametrizable functors.
class All
{
public:
bool operator()(const PopulationMember* entity) const
{
return true;
}
};
class AscByID
{
public:
bool operator()(const PopulationMember* a, const PopulationMember* b) const
{
return a->getId() < b.getId();
}
};
template<typename Entity, class Predicate, class SortComparator>
class Query
{
public:
typedef std::set<Entity, SortComparator> ResultSet;
Query(const Predicate& predicate = Predicate(), const SortComparator& cmp = SortComparator()) :
predicate(predicate), resultSet(cmp)
{
}
bool operator()(const Entity& entity)
{
if (predicate(entity))
{
resultSet.insert(entity);
return true;
}
return false;
}
const ResultSet& getResult(void) const
{
return resultSet;
}
void clearResult(void)
{
resultSet.clear();
}
private:
Predicate predicate;
ResultSet resultSet;
};
int main()
{
Query<const PopulationMember*, All, AscByID> query;
Popuation::execute(query);
//do something with the result
query.getResult();
//clear the result
query.clearResult();
//query again
Popuation::execute(query);
//do something useful again
return 0;
}
I need a shared_ptr like object, but which automatically creates a real object when I try to access its members.
For example, I have:
class Box
{
public:
unsigned int width;
unsigned int height;
Box(): width(50), height(100){}
};
std::vector< lazy<Box> > boxes;
boxes.resize(100);
// at this point boxes contain no any real Box object.
// But when I try to access box number 50, for example,
// it will be created.
std::cout << boxes[49].width;
// now vector contains one real box and 99 lazy boxes.
Is there some implementation, or I should to write my own?
It's very little effort to roll your own.
template<typename T>
class lazy {
public:
lazy() : child(0) {}
~lazy() { delete child; }
T &operator*() {
if (!child) child = new T;
return *child;
}
// might dereference NULL pointer if unset...
// but if this is const, what else can be done?
const T &operator*() const { return *child; }
T *operator->() { return &**this; }
const T *operator->() const { return &**this; }
private:
T *child;
};
// ...
cout << boxes[49]->width;
Using boost::optional, you can have such a thing:
// 100 lazy BigStuffs
std::vector< boost::optional<BigStuff> > v(100);
v[49] = some_big_stuff;
Will construct 100 lazy's and assign one real some_big_stuff to v[49]. boost::optional will use no heap memory, but use placement-new to create objects in a stack-allocated buffer. I would create a wrapper around boost::optional like this:
template<typename T>
struct LazyPtr {
T& operator*() { if(!opt) opt = T(); return *opt; }
T const& operator*() const { return *opt; }
T* operator->() { if(!opt) opt = T(); return &*opt; }
T const* operator->() const { return &*opt; }
private:
boost::optional<T> opt;
};
This now uses boost::optional for doing stuffs. It ought to support in-place construction like this one (example on op*):
T& operator*() { if(!opt) opt = boost::in_place(); return *opt; }
Which would not require any copy-ing. However, the current boost-manual does not include that assignment operator overload. The source does, however. I'm not sure whether this is just a defect in the manual or whether its documentation is intentionally left out. So i would use the safer way using a copy assignment using T().
I've never heard of such a thing, but then again there are lots of things I've never heard of. How would the "lazy pointer" put useful data into the instances of the underlying class?
Are you sure that a sparse matrix isn't what you're really looking for?
So far as I know, there's no existing implementation of this sort of thing. It wouldn't be hard to create one though.