Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Vanadium
Jan 8, 2005

Avenging Dentist posted:

Yes, the Boost documentation. Where else would it be?

Who knows, perhaps in the vault, perhaps the documentation is only in svn, or on the library's non-boost page or something. :v:

Edit: goddamnit I was planning on sleeping tonight :gonk:

Vanadium fucked around with this message at 03:32 on Feb 8, 2009

Adbot
ADBOT LOVES YOU

That Turkey Story
Mar 30, 2003

Vanadium posted:

Who knows, perhaps in the vault, perhaps the documentation is only in svn, or on the library's non-boost page or something. :v:

Only if what you are looking for isn't yet a part of an official boost release.

Super Dude
Jan 23, 2005
Do the Jew
I probably should have explained a little bit better. (I'm using C, so I don't think I can use boost)

Say I have the number

01011001 10100011

and I want to get the value for the range in bold (the value 6).

oldkike
Jan 10, 2003

hey

www.pleasegimmeadollar.com

Super Dude posted:

I probably should have explained a little bit better. (I'm using C, so I don't think I can use boost)

Say I have the number

01011001 10100011

and I want to get the value for the range in bold (the value 6).


You need to shift it right by 10 bits, and then mask off the part you want:

code:
short your_number = 0x59a3;
int six = (your_number >> 10) & 0x7;

That Turkey Story
Mar 30, 2003


Hey, eat my butt!

Let's see you do it a better way :colbert:

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

That Turkey Story posted:

Hey, eat my butt!

Let's see you do it a better way :colbert:

Boom: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2378.pdf

That Turkey Story
Mar 30, 2003


Let us now travel into the future!

julyJones
Feb 12, 2007

Stopped making sense.
I'm imagining a listing of useful, common things for people like myself who aren't very familiar with them. I'm not finding anything on Google though. I guess you just have to browse the libraries and read all their descriptions.

Super Dude
Jan 23, 2005
Do the Jew

oldkike posted:

You need to shift it right by 10 bits, and then mask off the part you want:

code:
short your_number = 0x59a3;
int six = (your_number >> 10) & 0x7;

Ohhh I get it now. Thanks!

Smackbilly
Jan 3, 2001
What kind of a name is Pizza Organ! anyway?

Super Dude posted:

Ohhh I get it now. Thanks!

Also be careful with using shifts and bitwise operators in the same statement without parentheses. Bitwise operators have higher precedence than shifts, so your original code x >> 10 & 0xD is actually equivalent to x >> (10 & 0xD), and I don't think that's what you meant to write.

That Turkey Story
Mar 30, 2003

Smackbilly posted:

Also be careful with using shifts and bitwise operators in the same statement without parentheses. Bitwise operators have higher precedence than shifts, so your original code x >> 10 & 0xD is actually equivalent to x >> (10 & 0xD), and I don't think that's what you meant to write.

No it isn't. The parenthesis are not necessary, though you probably should write them anyway for clarity.

Thug Bonnet
Sep 22, 2004

anime tits ftw

What is the proper way to enforce type safety via argument with polymorphic classes? For example what if in the following code I wanted to make a derivative of my container class that would only take B* as the argument to add(), rather than ACont which takes A*.

code:
#include <list>

class A{
	public:
		A(){};
		virtual ~A(){};
};

class B: public A{
	public:
		B(){};
		~B(){};
};

class C: public A{
	public:
		C(){};
		~C(){};
};

class Cont{
	public:
		Cont(){};
		virtual ~Cont(){};
		virtual void add(A*)=0;

	protected:
		std::list<A*> l;

class ACont: public Cont{
	public:
		ACont(){};
		~ACont(){};

		void add(A* a){
			l.push_back(a);
		};

};
int main(){
	ACont * ac = new ACont();
	A* b = new B();
	A* c = new C();

	ac->add(b);
	ac->add(c);

	return 0;
};
For example:
code:
class BCont: public Cont{
	public:
		BCont(){};
		~BCont(){};

		void add(B* b){
			l.push_back(b);
		};
};
The problem here is obviously making void Cont::add() virtual doesn't help because the arguments are part of the prototype, e.g. void add(A*) != void add(B*) so it won't be properly overridden (or in this case satisfy the requirement to implement void add(A*) ).

Thug Bonnet fucked around with this message at 05:22 on Feb 9, 2009

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
The proper way is to avoid doing that at all. There's no way you're going to get compile-time type safety for BCont, since imagine what would happen if you were using it via a Cont pointer. The compiler wouldn't be able to tell that it should be using the types associated with BCont.

One solution (used by the STL, obviously) is to take advantage of compile-time polymorphism with the use of templates. Depending on your requirements, you may also choose to remove Cont::add[fixed] and have [fixed]add only appear in the subclasses, thus requiring you to use a (A|B)Cont if you want to insert objects.

More about this here: http://www.parashift.com/c++-faq-lite/proper-inheritance.html#faq-21.3

Thug Bonnet
Sep 22, 2004

anime tits ftw

Dang, I was just combing through c++-faq-lite. I had a feeling it had the answer, I just couldn't find it.

I'd really like to avoid templates for this for a number of reasons. I guess I need to re-think it. I'm glad to know I wasn't just missing something, though :)

Avenging Dentist posted:

Depending on your requirements, you may also choose to remove Cont::add and have add only appear in the subclasses, thus requiring you to use a (A|B)Cont if you want to insert objects.

But this would mean I can't guarantee you can add() in some instances (for example passing the interface pointer).

Thug Bonnet fucked around with this message at 06:24 on Feb 9, 2009

ShoulderDaemon
Oct 9, 2003
support goon fund
Taco Defender

Thug Bonnet posted:

But this would mean I can't guarantee you can add() in some instances (for example passing the interface pointer).

You simply can't safely add anything given an interface pointer. You're only allowed to add something that's the same class, but given only the interface you don't know what class that is, so there's no way you can add anything. This is the same reason a vector of Cars isn't a vector of Vehicles.

Thug Bonnet
Sep 22, 2004

anime tits ftw

ShoulderDaemon posted:

You simply can't safely add anything given an interface pointer. You're only allowed to add something that's the same class, but given only the interface you don't know what class that is, so there's no way you can add anything. This is the same reason a vector of Cars isn't a vector of Vehicles.

Ah, a lightbulb just went on. This makes things marginally more complicated then :(

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
A really, really hacky option would be to ensure that you have the correct type by using a dynamic_cast, but I really don't recommend that. (Also it obviously only works at runtime).

Thug Bonnet
Sep 22, 2004

anime tits ftw

Avenging Dentist posted:

A really, really hacky option would be to ensure that you have the correct type by using a dynamic_cast, but I really don't recommend that. (Also it obviously only works at runtime).

Well i mean its not THAT hacky, and in fact has been recommended to me. But it just feels.. dirty. And doesn't really help all that much because what, you just silently ignore bad input? Not a wonderful solution.

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

Thug Bonnet posted:

Well i mean its not THAT hacky, and in fact has been recommended to me. But it just feels.. dirty. And doesn't really help all that much because what, you just silently ignore bad input? Not a wonderful solution.

You'd throw an exception or assert or something.

Contero
Mar 28, 2004

Here's what I would like to do. I want to implement a small scripting language in my C++ programs. What I'd like to know is what would be the best way to implement this.

Why? I'd like to be able to plug custom functionality into some of my programs at runtime. Right now I'd like to use it in a small graphical program so that I can rapidly play with / write new AI for some agents or something. In the future I'd like to use it for scripted behaviors / events on a networked game server.

Things I've considered:
  • Compiling and dynamically linking C code at runtime (barf)
  • Rolling my own language with yacc/antlr/boost::spirit (probably unnecessary)
  • Using something that's already out there (where you guys come in!)

So what I'd like to be able to do in my code is this:
code:
void moveToTheLeft(int feet) {...}

CustomBehavior b;
b.addFunction(moveToTheLeft, "moveToTheLeft");
b.loadFromFile("mySweetScript.txt");
int result = b.run("myFunction", 5);
Where "mySweetScript.txt" is:
code:
//(javascript??)
function myFunction (x)
{
   moveToTheLeft(x);
   return x * x;
}
Requirements:
  • Create and run new scripts at runtime
  • Able to expose some C++ functions to the scripts like getPosition() or something. Not all information needs to be passed in as a parameter. The names of exposed functions can be known at compile time.

Wish List:
  • If possible, I'd like the script language to be Python or something lisp-like (Scheme is cool)
  • Run specific functions out of a script, not just the script as a whole.
  • Scripts can save state information between runs
  • And the amount of state data can be determined upon scanning the script at runtime
  • And there can be multiple instances of this state data (multiple agents using the same behavior, but in different states).
  • linux or windows
  • Parses only once upon scanning the file, not every time the script is needed. (and only once for many instances of state info)
  • Fast! If possible. Maybe compiles to bytecode instead of staying an AST? (Java? oh god)
  • Runs in a sanitary environment (can't crash the server, delete files etc...)
  • If a script blows up I can clean it up and signal some sort of useful error. ("You tried to add a pointer and a float on line 30!" or at least "error on line 30")
  • Be able to analyze a script to determine if it will run forever (I kid)

I'm sure there are libraries that do a good chunk of this sort of thing. I just don't know what they are or which ones are the most useful etc. Can you guys point me in the right direction? Or are my requirements too absurd and I should just try to make my own language (and fail miserably)?

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
Use Boost.Python? Lua/Luabind?

Lua is pretty drat lightweight and runs well on embedded systems. Python is a little more heavyweight but has better libraries (not really an issue for application extensibility, though). Lua is used in lots of games, too: Dawn of War, Sam and Max, both STALKER games, etc.

Also, I'm one of the Luabind developers. :)

Avenging Dentist fucked around with this message at 02:54 on Feb 10, 2009

ShoulderDaemon
Oct 9, 2003
support goon fund
Taco Defender
Lua is probably the most commonly used embedded languags for this sort of thing.

If you really want a scheme, you can use guile, the embedded scheme interpreter.

Contero
Mar 28, 2004

Luabind looks fantastic. Thank you so much.

ShoulderDaemon posted:

If you really want a scheme, you can use guile, the embedded scheme interpreter.

I'll check this out also.

POKEMAN SAM
Jul 8, 2004

Contero posted:

Luabind looks fantastic. Thank you so much.


I'll check this out also.

Just roll your own Scheme interpreter; the language is trivial.

:colbert:

tef
May 30, 2004

-> some l-system crap ->
(that is if you leave out little implementation details like call/cc)

narfanator
Dec 16, 2008
Hi; I'm having trouble making lists of a templated class:

I'm working in Visual Studio 2008, C++

code:
#include <list>

template<class T> class bar
{
public:
   bool isBar;
   bar()         : isBar(true){}
   bar(bar<T> &b): isBar(b.isBar){}
};

int main()
{
   std::list<bar<double> > l;
   l.resize(10);

   return 0;
}
This code is generating error error C2558: class 'bar<T>' : no copy constructor available or copy constructor is declared 'explicit'

The error is only generated if I try to use the list (such as the resize), which makes sense and all.

Actual intended use questions:
Will I have further problems if the class I'm templating on, is itself a templated class?
Will I have further problems if either of those classes are themselves, or inheriting from, "curiously recurring template pattern" classes?
(CRTP = class b : public t<b> )

Thanks!

EDIT: CRTP was wrong.

narfanator fucked around with this message at 05:17 on Feb 11, 2009

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

tef posted:

(that is if you leave out little implementation details like call/cc)

call/cc is really easy if you (1) understand Landin's paper (which is extraordinarily transparent) and (2) write your interpreter in CPS. The alternatives might be pretty obnoxious.

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

narfanator posted:

Hi; I'm having trouble making lists of a templated class

Your copy ctor needs to take a const reference. Also, you don't need to explicitly specify the template class inside of the class template (i.e. bar works where you have bar<T>).

narfanator
Dec 16, 2008
#$*#% const.

Thanks.

TSDK
Nov 24, 2003

I got a wooden uploading this one

Contero posted:

I'm sure there are libraries that do a good chunk of this sort of thing. I just don't know what they are or which ones are the most useful etc. Can you guys point me in the right direction? Or are my requirements too absurd and I should just try to make my own language (and fail miserably)?
Scripting languages also worth considering:
One of the most important features you should be looking at is the handling of threading within the scripting languages. Entity scripts become much easier to write if you can have dozens of script instances sleeping in logic loops and only waking up when something relevant to that entity happens.

newsomnuke
Feb 25, 2007

TSDK posted:

Scripting languages also worth considering:
One of the most important features you should be looking at is the handling of threading within the scripting languages. Entity scripts become much easier to write if you can have dozens of script instances sleeping in logic loops and only waking up when something relevant to that entity happens.
I was going to mention something along these lines. I've been working with GameMonkey for the past couple years and it's simply wonderful. Lightweight, the source is compact and easy to understand, and the language is small but surprisingly flexible. Really, I could go on and on about it (and I will, if you ask me). It makes 'threading' a breeze.

The problem is the support. It's got a tiny userbase, and a definite lack of tutorials and I'm sure it's this which is hampering its wider adoption.

DoctorTristan
Mar 11, 2006

I would look up into your lifeless eyes and wave, like this. Can you and your associates arrange that for me, Mr. Morden?
Quick and stupid question: I'm writing a smart container that owns the pointers I push to it, and I want to ensure that the objects these point to are unchanged for their lifetime.

Can I do this as:

code:
class MyContainer {
  
  typedef std::vector<MyObject*> PStore;

  PStore storage;
  ...

public:
  MyContainer();
  ~MyContainer();
  ...
  push_back( const MyObject* obj ) {
    storage.push_back( obj )
  }

};

MyContainer::~MyContainer() {
  typename std::vector<MyObject*>::iterator i = storage.end();
  while( i != storage.begin() ) {
    delete i;
    i = 0;
  }
}

Is there any problem in insisting that push_back() takes a pointer to a const MyObject, and have I managed to avoid screwing up my iterators in the destructor definition?

Mustach
Mar 2, 2003

In this long line, there's been some real strange genes. You've got 'em all, with some extras thrown in.
PStore should be a vector of const MyObject*s, push_back() needs a return type, that while-loop is infite if storage contains at least one element actually it'll cause some other problem because i is not a MyObject*, and (related to the previous) I don't know what you're trying to do with i = 0, but it's not the right thing. edit: Actually there's way more problems, hold on

I'm guessing that you just made a whole bunch of typos and meant to type something like this:
code:
template<class MyObject>
class MyContainer {
  typedef std::vector<const MyObject*> PStore;
  PStore storage;
  ...
public:
  MyContainer();
  ~MyContainer();
  ...
  void push_back( const MyObject* obj ) {
    storage.push_back( obj )
  }
};

MyContainer::~MyContainer() {
  PStore::iterator i = storage.begin();
  while( i != storage.end() ) {
    delete *i;
    ++i;
  }
}

Mustach fucked around with this message at 21:23 on Feb 10, 2009

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

DoctorTristan posted:

Is there any problem in insisting that push_back() takes a pointer to a const MyObject, and have I managed to avoid screwing up my iterators in the destructor definition?

A pointer-to-const-object only guarantees (well, "guarantees") that the object can't be changed through that pointer and no more; to actually guarantee that no-one can change the object at all, you'd have to guarantee that nothing out there has a pointer-to-non-const-object to it, which is not possible to prove via the type system. Also, a quick mechanical point: you take in the pointer-to-const and immediately try to put it in a collection of pointer-to-non-const, which is a violation; you need that to be std::vector<const MyObject*>.

Your iterators are totally screwed up. If you're trying to iterate through the vector backwards, (1) you need special iterators for that (rbegin and rend), and (2) you need to actually update the iterator at some point, like so:

code:
MyContainer::~MyContainer() {
  typename std::vector<const MyObject*>::reverse_iterator ir = storage.rbegin();
  while (ir != storage.rend()) {
    delete *ir;
    ++ir;  // Note that it's ++ despite drat well going backwards
  }
}

DoctorTristan
Mar 11, 2006

I would look up into your lifeless eyes and wave, like this. Can you and your associates arrange that for me, Mr. Morden?

Mustach posted:

PStore should be a vector of const MyObject*s, push_back() needs a return type, that while-loop is infite if storage contains at least one element, and (related to the previous) I don't know what you're trying to do with i = 0, but it's not the right thing.

:doh:

I swear that some of those mistakes only crept in when I wrote up that post...

I wasn't quite sure abot the i=0 thing myself actually, I actually stole it from a generic purging template function from Eckel vol. 2, I assumed it was some kind of safety feature that I didn't quite get. What he wrote was:

code:
template<class Seq> void purge(Seq& c) {
  typename Seq::iterator i;
  for(i = c.begin(); i != c.end(); ++i) {
    delete *i;
    *i = 0;
  }
}

Mustach
Mar 2, 2003

In this long line, there's been some real strange genes. You've got 'em all, with some extras thrown in.
Okay, that makes sense, because *i = 0 assigns to the element, but i = 0 assigns to the iterator. Although you don't need to reassign the elements in the destructor, since the the vector's going to be destroyed right after.

Check out my edit and rjmccall's post for more corrections and info.

DoctorTristan
Mar 11, 2006

I would look up into your lifeless eyes and wave, like this. Can you and your associates arrange that for me, Mr. Morden?
Great, thanks guys. Some of those stupid errors were typos, but a lot were just me being plain dumb.

That Turkey Story
Mar 30, 2003

narfanator posted:

Will I have further problems if either of those classes are themselves, or inheriting from, "curiously recurring template pattern" classes?
(CRTP = template <class t> class b : public t )

That is not CRTP. CRTP is class b : some_template< b > {};

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

rjmccall posted:

Your iterators are totally screwed up. If you're trying to iterate through the vector backwards, (1) you need special iterators for that (rbegin and rend),

That's not true. rbegin and rend are meant to be used with the generic STL algorithms when you need to do something in reverse. If you're making the loop yourself, you can (and many times should) use regular iterators: http://codepad.org/jKL4tmqk .

Reverse iterators don't always have very good support in the STL. Off the top of my head, I know that you can't use a reverse iterator to erase parts of a string, but a regular iterator works just fine.

Adbot
ADBOT LOVES YOU

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
Okay. I wasn't sure if decrementing end was actually specified behavior; obviously it works given a simple implementation.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply