Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I need a struct that can hold 3 coordinates as separate variables, but I also need a way to iterate through them. For now, I am doing it like this:
struct Vector3
{
float coords[3];
float& x = coords[0];
float& y = coords[1];
float& z = coords[2];
};
This way I can access each individual variable as well as iterate through all of them using the coords array. Problem is: this is very unefficient, both in memory usage and in performance cost. Is there a better solution?
As suggest (by underscore_d) in a comment the preferred way is to provide accessor functions.
On any realistic compiler they'll be optimised away so no space or performance issue.
struct Vector3 {
float coords[3];
float& x() { return coords[0]; }
float& y() { return coords[1]; }
float& z() { return coords[2]; }
float x() const { return coords[0]; }
float y() const { return coords[1]; }
float z() const { return coords[2]; }
};
Here's a little program that gives it a run out.
#include <iostream>
struct Vector3 {
float coords[3];
float& x() { return coords[0]; }
float& y() { return coords[1]; }
float& z() { return coords[2]; }
float x() const { return coords[0]; }
float y() const { return coords[1]; }
float z() const { return coords[2]; }
};
void dump(const std::string& title,const Vector3& v3){
std::cout << title << '\n';
std::cout << "{ " << v3.coords[0] << " , " << v3.coords[1] << " , " << v3.coords[2] << " }\n";
std::cout << "x=" << v3.x() << " y=" << v3.y() << " z=" << v3.z() << '\n' << std::endl;
}
int main() {
Vector3 v3{};
dump("v3 0:",v3);
v3.x()=7.0f;
v3.y()=3.141f;
v3.z()=276.0f;
dump("v3 1:", v3);
Vector3 v3c{};
dump("v3 c 0:", v3c);
v3c=v3;
dump("v3 c 1:",v3c);
return 0;
}
Don't overlook that the assignment v3c=v3 now works 'out of the box'. Bonus!
The references broke the default assignment operator. References can't be assigned to be references to other things (in this case the coordinate in the other object - as C++ sees it).
I've provided two sets of getters - const and non-const - you may not be managing const-ness.
You mention iteration. If you this to the structure definition:
const float * begin() const { return coords;}
const float * end() const { return coords + 3; /* Yes 3 */}
float * begin() { return coords;}
float * end() { return coords + 3; /* Yes 3 */}
You can use C++ ranged-for loops : for(auto curr : vec ) as well.
This snippet sets all the coords of v3 to 7.0.
for(auto& curr : v3){
curr=7.0f;
}
I also recommend adding a constructor: Vector3():coords{} {} to the struct to initialise all the coordinates to zero. It has a tiny overhead but experience shows its usually the best to avoid 'weird' bugs down the line.
The modern recommendation is to prefer double over float unless you have good reason. I at least recommend creating a master typedef float float_type; and using that consistently in your code. It won't save you any re-engineering but it will reduce the rework if you change take. Also observe "almost always auto".
constexpr float_type zero{0}; may also help.
Expected program output:
v3 0:
{ 0 , 0 , 0 }
x=0 y=0 z=0
v3 1:
{ 7 , 3.141 , 276 }
x=7 y=3.141 z=276
v3 c 0:
{ 0 , 0 , 0 }
x=0 y=0 z=0
v3 c 1:
{ 7 , 3.141 , 276 }
Iterate through variables in a struct c++
There is no standard way to do this.
You could for example implement a custom iterator to do this. However, for random access, an array is likely to produce efficient code.
This way I can access each individual variable as well as iterate through all of them using the coords array. Problem is: this is very unefficient
You don't need the references to access individual elements. This works just fine:
struct Vector3
{
float coords[3];
} v;
v.coords[0] = 42; // access first element
The essence of what I want to do is to take two instances of Vector2D and create a third vector that is to be returned and made into the third instance. The problem I am facing is that I am not entirely sure on how to go ahead in doing so. I have tried to find the syntax for sending in instances, if there is such a one, but I have not managed to find anything useful in any of my books.
#include<iostream>
#include<string>
#include<array>
using namespace std;
class vector2D
{
public:
array<float, 2> get()
{
return xy_coord;
}
void set(float x, float y)
{
xy_coord[0] = x;
xy_coord[1] = y;
}
array<float, 2> vectorAdd(a, b)
{
array<float, 2> c;
for (int i = 0; i < 2; i++)
{
c[i] = a[i] + b[i];
}
return c;
}
private:
array<float, 2> xy_coord;
};
int main()
{
string y;
vector2D a, b, c;
array<float, 2> temp;
a.set(2.0, 3.0);
b.set(4.0, 5.0);
temp = c.vectorAdd(a, b);
c.set(temp[0], temp[1]);
getline(cin, y);
}
The idea is to send in the instances a and b to vectorAdd and sum them up and then set c equal to the returned value (I am sure there is a better way to write the code in the main(), but I am not sure how). In short, what would a and b need to be defined as to make this work, assuming it can work at all.
Maybe you could do something like this instead, so you don't have to pass array around:
#include <iostream>
class Vector2D
{
private:
double _x;
double _y;
public:
Vector2D() = delete;
Vector2D(double x, double y) : _x(x), _y(y) {}
double X() const { return _x; }
double Y() const { return _y; }
Vector2D operator+(Vector2D const &v) const
{
return Vector2D(X() + v.X(), Y() + v.Y());
}
};
int main()
{
Vector2D v1(10.0, 20.0);
Vector2D v2(100.0, 200.0);
Vector2D v3 = v1 + v2;
std::cout << v3.X() << " " << v3.Y();
return 0;
}
Prints:
110 220
Do you need to use array<float, 2>? Have you thought of using pair<float, float>?
A lot (all?) of the operations that you have in your Vector2D class come for free with Pair<>.
Then you just create operator+ as others have suggested.
#include <iostream>
#include <utility>
using namespace std;
using Coord = pair<float, float>;
template <typename L, typename R>
Coord operator+(const L& x, const R& y) { return std::make_pair(x.first + y.first, x.second + y.second); }
int main()
{
Coord a { 5.0f, 6.0f };
Coord b { 7.0f, 9.0f };
Coord c = a + b;
std::cout.precision(5);
std::cout << "c= (" << std::fixed << c.first << ", " << c.second << ")" << std::endl;
return 0;
}
I have data laid out in memory in a Structure of Arrays (SoA) or Sturcture of Pointers (SoP) form, and have a way to access that data as though it were laid out in Array of Structure (AoS) form -- code given below.
However, I am not too happy about use of struct AoS_4_SoP -- although this struct appears to use templates, it is not really generic since, for example, foo and bar are hard-coded inside it.
Two questions/requests:
1) For read-write performance, is AoS access provided as good as the direct SoA access?
2) What would a more generic scheme be? (I have seen quamrana's code here, but it hasn't helped.)
struct SoP{ // Structure of Pointers
int *foo{ nullptr };
double *bar{ nullptr };
SoP( int *xi, double *xd ):foo(xi), bar(xd){};
};
struct SoR{ // Structure of References
int &foo;
double &bar;
SoR( int &xi, double &xd ):foo(xi), bar(xd){};
};
template< typename T, typename S >
struct AoS_4_SoP {
AoS_4_SoP( T *x ) : p( x ){};
T *p;
S operator[](std::size_t idx) const { return { p->foo[idx], p->bar[idx] }; }
const S operator[](std::size_t idx) const { return { p->foo[idx], p->bar[idx] }; }
};
Here's a main() showing the use of the above:
int main()
{
std::vector< int > ibuf{ 11, 22, 33, 44 };
std::vector< double > dbuf{ 0.11, 0.22, 0.33, 0.44 };;
SoP x_sop( ibuf.data(), dbuf.data() );
ibuf.at(2) = 333;
std::cout << "Access via SoP syntax:\n "
<< x_sop.foo[2]
<< " "
<< x_sop.bar[2] << std::endl;
AoS_4_SoP<SoP, SoR> xacc( &x_sop );
std::cout << "Access via AoS syntax:\n "
<< xacc[2].foo
<< " "
<< xacc[2].bar << std::endl;
// show write access via SoA syntax
ibuf.at(2) = 3333;
dbuf.at( 2 ) = 0.333333; // will get overwritten below
xacc[2].bar = 0.3333;
std::cout << "Values written via SoP, read via SoP:\n "
<< x_sop.foo[2]
<< " "
<< x_sop.bar[2] << std::endl;
// show write access via AoS syntax
xacc[2].foo = 333333;
dbuf.at( 2 ) = 0.3333333333; // will get overwritten below
xacc[2].bar = 0.333333;
std::cout << "Values written via AoS, read via AoS:\n "
<< xacc[2].foo
<< " "
<< xacc[2].bar << std::endl;
}
Above code can be compiled via:
// x86_64-w64-mingw32-g++.exe -D_WIN64 -Wall -Wextra -Werror -std=c++11 -O3 -static-libgcc -static-libstdc++ aossoa.cc -o aossoa.exe
and results in the following output:
Access via SoP syntax:
333 0.33
Access via AoS syntax:
333 0.33
Values written via SoP, read via SoP:
3333 0.3333
Values written via AoS, read via AoS:
333333 0.333333
I think this template will work.
template<class T, class U, class D, class S>
struct Accessor {
T* p;
U* (T::*pFirst);
D* (T::*pSecond);
S operator[](size_t index) {
return {(p->*pFirst)[index], (p->*pSecond)[index]};
}
Accessor(T* p_, U * (T::*pF), D * (T::*pS)): p(p_), pFirst(pF), pSecond(pS) {}
};
void main() {
std::vector< int > ibuf{ 11, 22, 33, 44 };
std::vector< double > dbuf{ 0.11, 0.22, 0.33, 0.44 };;
SoP x_sop(ibuf.data(), dbuf.data());
Accessor<SoP, int, double, SoR> aos(&x_sop, &SoP::foo, &SoP::bar);
aos[0].foo;
}
Now the template Accessor knows nothing about the names of the members of T.
At least it compiles under VS2015
Here's my adaptation of quamrana's solution for the "inverse" use case (SoA access for AoS):
template<class T, class S, class M0, class M1>
struct Accessor2{
T* p;
M0 m0;
M1 m1;
S operator[](std::size_t idx) { return { m0[idx], m1[idx] }; }
const S operator[](std::size_t idx) const { return { m0[idx], m1[idx] }; }
Accessor2(T* x, M0 p0, M1 p1): p(x), m0(p0), m1(p1){}
};
template< typename T, typename S >
struct AoS_4_SoP : public Accessor2<T, S, decltype(T::foo), decltype(T::bar)>
{
#ifndef COMPILER_CAN_INFER_PARENT_CLASS_TEMPLATE_SPECIFICATION
AoS_4_SoP(T *x) : Accessor2<T, S, decltype(T::foo), decltype(T::bar)>
(x, x->foo, x->bar ){}
#else
AoS_4_SoP(T *x):Accessor2(x, x->foo, x->bar ){}
#endif
};
Regarding the #ifndef COMPILER_CAN_INFER_PARENT_CLASS_TEMPLATE_SPECIFICATION, the compiler I am using viz, g++ 6.2.0 (x86_64_6.2.0_posix_seh_rt_v5_rev1/mingw64/bin/x86_64-w64-mingw32-g++.exe) is unable to infer the parent class' template specification. But, as Lightness Races in Orbit says on this page: the base's injected-class-name ought to be sufficient information for the compiler.
I have been surprised to find that boost::multi_array seems to allocate its initial elements differently from, say, std::vector. It does not seem to fill each element with a unique element (using its default value or default constructor). I'm having trouble finding more information about this.
Is there a way to make the multi_array fill itself with a unique object at each element?
For example, consider the following:
static int num = 0;
struct A {
int n;
A() : n((::num)++) {
std::cout << "A()" << std::endl;
}
virtual ~A() {}
void print() {
std::cout << "n=" << n << std::endl;
}
};
int main() {
std::cout << "vector:" << std::endl;
std::vector<A> v(3);
for (auto x : v) {
x.print();
}
std::cout << "multi:" << std::endl;
boost::multi_array<A, 2> m(boost::extents[2][2]);
for (auto x : m) {
for (auto y : x) {
y.print();
}
}
}
This results in the output:
vector:
A()
A()
A()
n=0
n=1
n=2
multi:
A()
n=3
n=3
n=3
n=3
Why is the constructor called only once for the multi_array? How can the multi_array be "filled out" with unique objects (using A's default constructor)?
To quickly fill the whole array do something like fill_n¹:
std::fill_n(a.data(), a.num_elements(), 0);
With boost multi_array you can use a view to your own memory buffer to get the same performance (std::uninitialized_copy is your friend). (actually, you could even map an array view on existing memory, and you want to keep the existing values).
I've written a comparative demo about this here: pointers to a class in dynamically allocated boost multi_array, not compiling
Live On Coliru
#include <boost/multi_array.hpp>
#include <type_traits>
#include <memory>
struct octreenode { int a; int b; };
class world {
public:
world(double x, double y, double z, int widtheast, int widthnorth, int height)
:
originx(x), originy(y), originz(z),
chunkseast(widtheast), chunksnorth(widthnorth), chunksup(height)
{
#define OPTION 4
#if OPTION == 1
static_assert(std::is_trivially_destructible<octreenode>::value, "assumption made");
//std::uninitialized_fill_n(chunk.data(), chunk.num_elements(), octreenode {1, 72});
std::fill_n(chunk.data(), chunk.num_elements(), octreenode {1, 72});
#elif OPTION == 2
for(auto a:chunk) for(auto b:a) for(auto&c:b) c = octreenode{1, 72};
#elif OPTION == 3
for (index cz = 0; cz < chunksnorth; ++cz) {
for (index cx = 0; cx < chunkseast; ++cx) {
for (index cy = 0; cy < chunksup; ++cy) {
chunk[cz][cx][cy] = octreenode{1, 72};
}
}
}
#elif OPTION == 4
static_assert(std::is_trivially_destructible<octreenode>::value, "assumption made");
for (index cz = 0; cz < chunksnorth; ++cz) {
for (index cx = 0; cx < chunkseast; ++cx) {
for (index cy = 0; cy < chunksup; ++cy) {
new (&chunk[cz][cx][cy]) octreenode{1, 72};
}
}
}
#endif
(void) originx, (void) originy, (void) originz, (void) chunksup, (void) chunkseast, (void) chunksnorth;
}
private:
double originx, originy, originz;
int chunkseast, chunksnorth, chunksup;
#if 1
typedef boost::multi_array<octreenode, 3> planetchunkarray; // a boost_multi for chunks
typedef planetchunkarray::index index;
planetchunkarray chunk{boost::extents[chunksnorth][chunkseast][chunksup]};
#else
static_assert(boost::is_trivially_destructible<octreenode>::value, "assumption made");
std::unique_ptr<octreenode[]> raw { new octreenode[chunksnorth*chunkseast*chunksup] };
typedef boost::multi_array_ref<octreenode, 3> planetchunkarray;
typedef planetchunkarray::index index;
planetchunkarray chunk{raw.get(), boost::extents[chunksnorth][chunkseast][chunksup]};
#endif
};
int main() {
world w(1,2,3,4,5,6);
}
The variant using multi_array_ref is an example of how to avoid copy-constructing the elements (it's akin to the optimization used by std::vector when it uses uninitialized memory for reserved but unused elements).
¹ Of course for unique values, use std::iota or std::generate
http://en.cppreference.com/w/cpp/algorithm/iota
http://en.cppreference.com/w/cpp/algorithm/generate_n
So on further study, I learned two things:
boost::multi_array uses the copy constructor to initialize objects into the container, not the default constructor.
The for (auto x : container) way of looping in C++11 seems (at least with clang++ 3.5) to loop over copies of the container elements, rather than iterators (or references).
Modifying the original question's example to demonstrate point 1.
Adding a copy constructor (and corresponding counter), and using auto& x for the object loops rather than auto x:
static int num = 0;
static int cpy = 0;
struct A {
int n;
int c;
A() : n((::num)++), c(0) {
std::cout << "A_def()" << std::endl;
}
A(const A& o) : n(0), c((::cpy)++) {
std::cout << "A_cpy()" << std::endl;
}
virtual ~A() {}
void print() {
std::cout << "n=" << n << ",c=" << c << std::endl;
}
};
int main() {
std::cout << "vector:" << std::endl;
std::vector<A> v(3);
for (auto& x : v) {
x.print();
}
std::cout << "multi:" << std::endl;
boost::multi_array<A, 2> m(boost::extents[2][2]);
for (auto x : m) {
for (auto& y : x) {
y.print();
}
}
}
Produces the output
vector:
A_def() // <- vector allocation starts
A_def()
A_def()
n=0,c=0 // <- vector printing starts, using "for (auto& x)"
n=1,c=0
n=2,c=0
multi:
A_def() // <- a temporary object for multi_array allocation
A_cpy() // <- multi_array allocation starts
A_cpy()
A_cpy()
A_cpy()
n=0,c=0 // <- multi_array prints starts, using "for (auto& y)"
n=0,c=1
n=0,c=2
n=0,c=3
Modifying the example above to demonstrate point 2.
Same class definition as above in this answer, but removing the auto& x from the object loops, and going back to using auto x as done in the original question.
std::cout << "vector:" << std::endl;
std::vector<A> v(3);
for (auto x : v) {
x.print();
}
std::cout << "multi:" << std::endl;
boost::multi_array<A, 2> m(boost::extents[2][2]);
for (auto x : m) {
for (auto y : x) {
y.print();
}
}
Produces output that shows the copy constructor gets called during the print loops, even for elements in the vector.
vector:
A_def() // <- vector allocation starts
A_def()
A_def()
A_cpy() // <- vector printing starts, using "for (auto x)"
n=0,c=0
A_cpy()
n=0,c=1
A_cpy()
n=0,c=2
multi:
A_def() // <- a temporary object for multi_array allocation
A_cpy() // <- multi_array allocation starts
A_cpy()
A_cpy()
A_cpy()
A_cpy() // <- multi_array printing starts, using "for (auto y)"
n=0,c=7
A_cpy()
n=0,c=8
A_cpy()
n=0,c=9
A_cpy()
n=0,c=10
Macros are fine.
Templates are fine.
Pretty much whatever it works is fine.
The example is OpenGL; but the technique is C++ specific and relies on no knowledge of OpenGL.
Precise problem:
I want an expression E; where I do not have to specify a unique name; such that a constructor is called where E is defined, and a destructor is called where the block E is in ends.
For example, consider:
class GlTranslate {
GLTranslate(float x, float y, float z); {
glPushMatrix();
glTranslatef(x, y, z);
}
~GlTranslate() { glPopMatrix(); }
};
Manual solution:
{
GlTranslate foo(1.0, 0.0, 0.0); // I had to give it a name
.....
} // auto popmatrix
Now, I have this not only for glTranslate, but lots of other PushAttrib/PopAttrib calls too. I would prefer not to have to come up with a unique name for each var. Is there some trick involving macros templates ... or something else that will automatically create a variable who's constructor is called at point of definition; and destructor called at end of block?
Thanks!
I would not do this personally but just come up with unique names. But if you want to do it, one way is to use a combination of if and for:
#define FOR_BLOCK(DECL) if(bool _c_ = false) ; else for(DECL;!_c_;_c_=true)
You can use it like
FOR_BLOCK(GlTranslate t(1.0, 0.0, 0.0)) {
FOR_BLOCK(GlTranslate t(1.0, 1.0, 0.0)) {
...
}
}
Each of those names are in separate scopes and won't conflict. The inner names hide the outer names. The expressions in the if and for loops are constant and should be easily optimized by the compiler.
If you really want to pass an expression, you can use the ScopedGuard trick (see Most Important const), but it will need some more work to write it. But the nice side is, that we can get rid of the for loop, and let our object evaluate to false:
struct sbase {
operator bool() const { return false; }
};
template<typename T>
struct scont : sbase {
scont(T const& t):t(t), dismiss() {
t.enter();
}
scont(scont const&o):t(o.t), dismiss() {
o.dismiss = true;
}
~scont() { if(!dismiss) t.leave(); }
T t;
mutable bool dismiss;
};
template<typename T>
scont<T> make_scont(T const&t) { return scont<T>(t); }
#define FOR_BLOCK(E) if(sbase const& _b_ = make_scont(E)) ; else
You then provide the proper enter and leave functions:
struct GlTranslate {
GLTranslate(float x, float y, float z)
:x(x),y(y),z(z) { }
void enter() const {
glPushMatrix();
glTranslatef(x, y, z);
}
void leave() const {
glPopMatrix();
}
float x, y, z;
};
Now you can write it entirely without a name on the user side:
FOR_BLOCK(GlTranslate(1.0, 0.0, 0.0)) {
FOR_BLOCK(GlTranslate(1.0, 1.0, 0.0)) {
...
}
}
If you want to pass multiple expressions at once, it's a bit more tricky, but you can write an expression template that acts on operator, to collect all expressions into a scont.
template<typename Derived>
struct scoped_obj {
void enter() const { }
void leave() const { }
Derived const& get_obj() const {
return static_cast<Derived const&>(*this);
}
};
template<typename L, typename R> struct collect
: scoped_obj< collect<L, R> > {
L l;
R r;
collect(L const& l, R const& r)
:l(l), r(r) { }
void enter() const { l.enter(); r.enter(); }
void leave() const { r.leave(); l.leave(); }
};
template<typename D1, typename D2>
collect<D1, D2> operator,(scoped_obj<D1> const& l, scoped_obj<D2> const& r) {
return collect<D1, D2>(l.get_obj(), r.get_obj());
}
#define FOR_BLOCK(E) if(sbase const& _b_ = make_scont((E))) ; else
You need to inherit the RAII object from scoped_obj<Class> like the following shows
struct GLTranslate : scoped_obj<GLTranslate> {
GLTranslate(float x, float y, float z)
:x(x),y(y),z(z) { }
void enter() const {
std::cout << "entering ("
<< x << " " << y << " " << z << ")"
<< std::endl;
}
void leave() const {
std::cout << "leaving ("
<< x << " " << y << " " << z << ")"
<< std::endl;
}
float x, y, z;
};
int main() {
// if more than one element is passed, wrap them in parentheses
FOR_BLOCK((GLTranslate(10, 20, 30), GLTranslate(40, 50, 60))) {
std::cout << "in block..." << std::endl;
}
}
All of these involve no virtual functions, and the functions involved are transparent to the compiler. In fact, with the above GLTranslate changed to add a single integer to a global variable and when leaving subtracting it again, and the below defined GLTranslateE, i did a test:
// we will change this and see how the compiler reacts.
int j = 0;
// only add, don't subtract again
struct GLTranslateE : scoped_obj< GLTranslateE > {
GLTranslateE(int x):x(x) { }
void enter() const {
j += x;
}
int x;
};
int main() {
FOR_BLOCK((GLTranslate(10), GLTranslateE(5))) {
/* empty */
}
return j;
}
In fact, GCC at optimization level -O2 outputs this:
main:
sub $29, $29, 8
ldw $2, $0, j
add $2, $2, 5
stw $2, $0, j
.L1:
add $29, $29, 8
jr $31
I wouldn't have expected that, it optimized quite well!
If your compiler supports __COUNTER__ (it probably does), you could try:
// boiler-plate
#define CONCATENATE_DETAIL(x, y) x##y
#define CONCATENATE(x, y) CONCATENATE_DETAIL(x, y)
#define MAKE_UNIQUE(x) CONCATENATE(x, __COUNTER__)
// per-transform type
#define GL_TRANSLATE_DETAIL(n, x, y, z) GlTranslate n(x, y, z)
#define GL_TRANSLATE(x, y, z) GL_TRANSLATE_DETAIL(MAKE_UNIQUE(_trans_), x, y, z)
For
{
GL_TRANSLATE(1.0, 0.0, 0.0);
// becomes something like:
GlTranslate _trans_1(1.0, 0.0, 0.0);
} // auto popmatrix
I think it's now possible to do something like this:
struct GlTranslate
{
operator()(double x,double y,double z, std::function<void()> f)
{
glPushMatrix(); glTranslatef(x, y, z);
f();
glPopMatrix();
}
};
then in the code
GlTranslate(x, y, z,[&]()
{
// your code goes here
});
Obviously, C++11 is needed
The canonical way as described in one answer is to use a lambda expression as the block, in C++ you can easily write a template function
with<T>(T instance, const std::function<void(T)> &f) {
f(instance);
}
and use it like
with(GLTranslate(...), [] (auto translate) {
....
});
but the most common reason for wanting a mechanism for avoiding defining names in your scope are long functions / methods that do lots of things. You might try a modern OOP / clean code inspired style with very short methods / functions for a change if this kind of problem keeps bothering you 🤔
Using C++17, a very simple macro leading to an intuitive usage:
#define given(...) if (__VA_ARGS__; true)
And can be nested:
given (GlTranslate foo(1.0, 0.0, 0.0))
{
foo.stuff();
given (GlTranslate foo(1.0, 2.0, 3.0))
{
foo.stuff();
...
}
}