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
Lakitu7
Jul 10, 2001

Watch for spinys
Fabulous. I'll get to reading. Thank you very much!

Adbot
ADBOT LOVES YOU

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.
Ignore him.

http://codepad.org/zwtgx7UU

Avenging Dentist
Oct 1, 2005

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

Mustach posted:

Ignore him.

http://codepad.org/zwtgx7UU

Iterators are awful. And he never mentioned that any of the other array classes met STL container requirements.

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.
Thanks, Andrei.

Avenging Dentist
Oct 1, 2005

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

Mustach posted:

Thanks, Andrei.

Oh also, your code is not appropriately generic since my example allows you to take advantage of overload resolution to do the following:

code:
template<typename T>
void something_fun(const T &t)
{
    // ...
    vnl_vector<double> vec = ToVNLVector(t); // works whether T is scalar or vector
}

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.
Thanks, Larry.

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
Iterators are really a pain to work with, and at least other languages encapsulated the begin and end iterators into one thing, though they almost universally ignored anything but ForwardIterators.

One day, I will write the STL++, which will use ranges and concepts and just generally be totally k-rad.

Also it will have matrices and trees and and and a pony!!

Avenging Dentist fucked around with this message at 01:26 on Jun 17, 2009

Ciaphas
Nov 20, 2005

> BEWARE, COWARD :ovr:


floWenoL posted:

If your intention is to work with an integer and a double containing the same integer value, a union is most definitely not what you want.

No, that wasn't my intent. I've got a class my predecessor wrote that stores one of either a numeric variable or a std::string, but instead of using a union (since you can't put std::strings in a union I guess) he just made one member variable for each type (int, short, char, long long, unsigned variants, and float/double) and zeroed out all the others when one got set, with one get/set for each type.

Sort of annoying to work with, so I was panning for ways to rewrite it.

Dijkstracula
Mar 18, 2003

You can't spell 'vector field' without me, Professor!

Yikes.

Ledneh posted:

(since you can't put std::strings in a union I guess)
It would require a bit more bookkeeping on your part to ensure doublefrees, memory leaks, segfaults, etc, don't happen, but why not hold a pointer to a malloced newed string?

Ciaphas
Nov 20, 2005

> BEWARE, COWARD :ovr:


Dijkstracula posted:

Yikes.
It would require a bit more bookkeeping on your part to ensure doublefrees, memory leaks, segfaults, etc, don't happen, but why not hold a pointer to a malloced newed string?

Yeah, it's not pleasant, given how irritatingly coupled this stupid thing is with the rest of the project. (not that I have any right to bitch, I've written far worse :()

Thanks for the suggestion on using a pointer instead. I also have had boost::any and/or boost::variant mentioned, but I know nothing about those so I guess it's readin' time.

There's so much I don't know :smith:

schnarf
Jun 1, 2002
I WIN.
What's the class being used for? It sounds like there's gotta be a nicer way to do that.

Ciaphas
Nov 20, 2005

> BEWARE, COWARD :ovr:


It's used for reading bits from a file buffer, with the type of data represented by those bits being known in advance (so we know bits 16-31 represent a 16 bit integer, 32-105 is a string of ascii characters, so on and so forth).

I thought about templatizing the class in question, but later there're vectors of objects of this class, and so far as I know you can't stuff a Foo<int> into a vector< Foo<float> >, for example. (Unless there's some trick that WOULD let me do that.) Closest I've been able to figure so far is paring it down to three types--int64, float64, and string--and three get/sets.

Which is only a less lovely solution and it bugs me that I can't think of anything else :(

The Red Baron
Jan 10, 2005

Re: unicode, I've spent some time the last few days implementing a tiny, working UTF conversion library and I'm interested in hearing some thoughts on the design/functionality. Again, this is something I'm writing primarily for my own needs, but if people are interested I could kick it into better shape and release it at some point.

The library currently concerns itself solely with conversion; it ~gives no poo poo~ about normalization, collation et al. The central notion is a templated transcoder iterator and several charset codecs, all exposed through views that model the range concept. Basically, to convert from charset X to Y, you can just write Y_view_of<X_source>(iterable-range) and get an iterable range that performs lazy, on-the-fly conversion with no dynamic allocation and also transparently handling the number of resulting characters.
code:
  std::string u8str("\x4d\xd0\xb0\xe4\xba\x8c\xf0\x90\x8c\x82");

  {
    // Works with ranges...
    BOOST_AUTO(conv32, utf32_view_of<utf8_source>(u8str));
    BOOST_FOREACH(utf32char_t uc, conv32)
    {
      std::cout << std::hex << uc << " "; // Output UTF-32 code points
    }
  }

  std::cout << "\n\n";
  {
    // ... and iterators
    BOOST_AUTO(conv16, utf16_view_of<utf8_source>(u8str.begin(), u8str.end()));
    BOOST_FOREACH(utf16char_t uc, conv16)
    {
      std::cout << std::hex << uc << " "; // Output UTF-16 code points (inc. surrogates)
    }
  }

  std::cout << "\n\n";
  {
    // Auto-selection of UTF-16/UTF-32 based on platform wchar_t
    BOOST_AUTO(wconv, utf_wchar_view_of<utf8_source>(u8str));

    std::wstring wtest(wconv.begin(), wconv.end());
  }

  {
    std::string test_str("Whøøy! Åaugh!");

    BOOST_AUTO(utfconv, utf8_view_of<iso8859_1_source>(test_str));

    std::copy(utfconv.begin(), utfconv.end(), std::ostream_iterator<char>(std::cout));
  }

  {
    // Convert an entire file from UTF-8 to UTF-16 without messing with
    // locales/collations
    std::ifstream ifs("../utf8src.txt", std::ios_base::binary);
    std::ofstream ofs("../utf16dest.txt", std::ios_base::binary);
    if (!ifs || !ofs)
      throw "barf";

    // Use custom binary iterators to avoid (i|o)stream_iterator formatting
    BOOST_AUTO(utfconv, utf16_view_of<utf8_source>(
        binary_istream_iterator<utf8char_t>(ifs),
        binary_istream_iterator<utf8char_t>()));

    std::copy(utfconv.begin(), utfconv.end(),
        binary_ostream_iterator<utf16char_t>(ofs));
  }
Since a view both accepts and returns an iterable range, it can be chained etc as usual. I'm currently working on getting support for dynamically chosen sources without this impairing inlining capabilities for non-dynamic sources.

Any thoughts?

Lexical Unit
Sep 16, 2003

Ledneh posted:

since you can't put std::strings in a union I guess
If you really, really wanted a union-like system where you could put std::string in there, you might see if Boost.Variant fits the bill. I'm not sure I understand exactly what you want to do, but it might be an option for you.

Chuu
Sep 11, 2004

Grimey Drawer
For some reason fstream isn't doing what I want it to do. I want it to add the string "0:1:2232:pirt" at the beginning of a file I open in truncate mode. We have:

code:
std::fstream m_file
m_file.open(m_filename.c_str(), std::ios_base::in | std::ios_base::out | std::ios_base::trunc);
m_file << "0:1:2232:" << "pirt" << std::endl;

OUTPUT:
1:2232:pirt
For some reason, it always strips the "0:". It will write out "0:" fine on any other line, just not at the beginning of the file. It doesn't matter how I format it it, << "0" << ":" << will strip it. x = 0; << x << ":" will strip it. << "0:1:2232:pirt" will strip it. Explicitly casting to a std::string will also still strip.

Substitute std::cout for m_file above, it prints fine.

What's special about "0:", and where is it documented?

Vanadium
Jan 8, 2005

This works fine. What are you using to look at the file?

Avenging Dentist
Oct 1, 2005

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

Chuu posted:

What's special about "0:", and where is it documented?

Nothing. You are probably using a stupid editor. Open the file in a hex editor or something.

Avenging Dentist
Oct 1, 2005

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

The Red Baron posted:

I'm currently working on getting support for dynamically chosen sources without this impairing inlining capabilities for non-dynamic sources.

Any thoughts?

Here's what I did. You might want to add in block encoding/decoding for rt_facet so that vtable lookups don't murder you (you'd hope that consecutive calls to the same virtual function would be optimized, but I doubt it). ct is short for "compile-time" and rt is "runtime":

code:
class char_facet
{
public:
    virtual unicode_t read(const void *&in) = 0;
    virtual void write(unicode_t c,void *&out) = 0;

    // Helper functions to work around runtime-determined size of characters
    virtual void eos(void *out) = 0;
    virtual bool more(const void *in) = 0;
};

template<typename T>
class rt_facet : private T,public char_facet
{
public:
    typedef typename T::char_type char_type;
    unicode_t read(const void *&in)
    {
        return T::read((const char_type *&)in);
    }
    void write(unicode_t c,void *&out)
    {
        T::write(c,(char_type *&)out);
    }
    void eos(void *out)
    {
        *(char_type *)out = 0;
    }
    bool more(const void *in)
    {
        return *(char_type *)in != 0;
    }
};

namespace ct
{
    class ascii
    {
    public:
        typedef char8_t char_type;
        unicode_t read(const char8_t *&in);
        void write(unicode_t c,char8_t *&out);
    };
}

namespace rt
{
    extern rt_encoding<ct::ascii> ascii;
}

Rapsey
Sep 29, 2005
Lets say I have a file descriptor array (fd is used as an index in the array). I can guarantee that I won't be writing to a specific fd from different threads.
Is it safe to use that table from multiple threads without locking?

TheSleeper
Feb 20, 2003
Just because you won't be writing to a specific fd more than once at the same time doesn't mean the array won't be modified by more than one thread.

Rapsey
Sep 29, 2005
Every thread has it's own set of file descriptors and they are used only within that thread. Multiple threads can use that same array, but naturally every fd is different and belongs to only one thread.

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

Rapsey posted:

Lets say I have a file descriptor array (fd is used as an index in the array). I can guarantee that I won't be writing to a specific fd from different threads.
Is it safe to use that table from multiple threads without locking?

If the "array" is truly an array and not some kind of container like a vector, then yes, you can access it without locking so long as you are sure that only one thread will ever try to access any single array element.

Arrays are just contiguous allocations of multiple values, so if two threads never use the same array index, the only thing shared is the address of the beginning of the array, which is constant.

If, however, you are using some sort of managed container (such as a std::vector) then this may or may not be safe depending on how you use it, and what guarantees are provided by the container. For example, if one thread performs an action that causes a vector to re-size, it may invalidate an iterator held by another thread.

Sweeper
Nov 29, 2007
The Joe Buck of Posting
Dinosaur Gum
Does anyone have a good resources on thread and how to use them? I've never done a whole lot with them and I find myself in the need of one :D

Should I use a separate library or just the standard thread stuff that comes with VS 2008?

Avenging Dentist
Oct 1, 2005

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

Sweeper posted:

Should I use a separate library or just the standard thread stuff that comes with VS 2008?

What standard thread stuff? TR1?

Sweeper
Nov 29, 2007
The Joe Buck of Posting
Dinosaur Gum

Avenging Dentist posted:

What standard thread stuff? TR1?
_beginthreadex CreateThread AFXBeginThread, sorry if I explained it incorrectly, the things that come with VS 2008.

Avenging Dentist
Oct 1, 2005

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

Sweeper
Nov 29, 2007
The Joe Buck of Posting
Dinosaur Gum

Avenging Dentist posted:

Download TR1.
I downloaded it with the feature pack for VS 2008, is that the right place to get it from? I'm pretty much a giant noob when it comes to this stuff.

Avenging Dentist
Oct 1, 2005

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

Sweeper posted:

I downloaded it with the feature pack for VS 2008, is that the right place to get it from? I'm pretty much a giant noob when it comes to this stuff.

Probably. I just use the Boost implementation.

Sweeper
Nov 29, 2007
The Joe Buck of Posting
Dinosaur Gum

Avenging Dentist posted:

Probably. I just use the Boost implementation.
Alright, so I got both the boost implementation and the VS 2008 implementation (why? dunno no reason really).

Do you have a link to any good resources on multi threading before I go scour the internet in hopes of finding something useful?

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
Threading is trivial. Synchronization is hard. The Little Book of Semaphores discusses (one way of) synchronization.

Sweeper
Nov 29, 2007
The Joe Buck of Posting
Dinosaur Gum

Avenging Dentist posted:

Threading is trivial. Synchronization is hard. The Little Book of Semaphores discusses (one way of) synchronization.
Alright, thanks :)

slovach
Oct 6, 2005
Lennie Fuckin' Briscoe
What is going on here?

I wrote a bitmap scaler and it reads the colors of the pixels to draw from the bytes of the bitmap it loaded.

code:
DWORD fart = index[(int)y_step * *bmi->width + (int)x_step] >> 8;
Under the debugger I can clearly see index has the right value (0xFF000000, shifted right 8 to make red), but if I try to assign it's value to anything, it gets garbage and as a result, completely hoses the colors of the picture.

Is this some kind of bizzaro compiler optimization gone horribly wrong? This only happens under Release.

slovach fucked around with this message at 00:04 on Jun 20, 2009

Runaway Five
Dec 31, 2007
I hate gays almost as much as I hate good posting. Also, God is good. Amen
Be careful when using bitshifts. The order of precedence they use CAN be weird. Put the stuff in >> completely inside of parenthesis ( )

See if that helps slovach.

POKEMAN SAM
Jul 8, 2004
I know it's from the previous page, but:

Otto Skorzeny posted:

Why are you looping through your array indices starting at 1 instead of 0

Post you quoted posted:

The top/bottom rows and side columns of Ex and Ey are to remain unchanged.

Dijkstracula
Mar 18, 2003

You can't spell 'vector field' without me, Professor!

slovach, can you post some code? Give an example of a value that you assign, and the garbage that get written in, and the code that does it? There's not much to work with here.

slovach
Oct 6, 2005
Lennie Fuckin' Briscoe

Dijkstracula posted:

slovach, can you post some code? Give an example of a value that you assign, and the garbage that get written in, and the code that does it? There's not much to work with here.

In the end it turned out to be my alpha blending routine that I tried to rewrite in assembly that mysteriously dies under Release.

I thought the compiler doesn't touch inline asm?

edit: And I figured it out. More like debug was actually saving me from my own mistake.

slovach fucked around with this message at 06:09 on Jun 21, 2009

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?
This is a bug I already fixed, but wanted to make sure I understood the problem correctly.

I was trying to create a bunch of MyObj objects on the heap, and push pointers to those objects into a vector<MyObj*> vec . I was (incorrectly) doing this by iterating:

code:
vec.push_back( new MyObj( args ) );
Which resulted in every element of vec pointing to the same memory location. Changing this to
code:

MyObj* pObj = new MyObj( args );
vec.push_back( pObj );
fixed the problem.

I *think* what was happening was that new was only creating temporary objects, so at the next iteration it went looking for another block of heap memory of the same size and found the same block as with the previous iteration. Is my guess right?


Edit: doing this didn't actually fix anything. See my post three posts down.

DoctorTristan fucked around with this message at 17:16 on Jun 22, 2009

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.

DoctorTristan posted:

I was (incorrectly) doing this by iterating:
What was in the for?

TSDK
Nov 24, 2003

I got a wooden uploading this one

DoctorTristan posted:

I *think* what was happening was that new was only creating temporary objects, so at the next iteration it went looking for another block of heap memory of the same size and found the same block as with the previous iteration. Is my guess right?
Almost certainly not. Posting some code would help.

Adbot
ADBOT LOVES YOU

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?
Okay, the change I posted above didn't actually fix the problem, just moved everything around a bit, so I'm back to where I started.

Mustach posted:

What was in the for?

No for, just a sequence of method calls that run a few test cases (sorry if this is an incorrect usage of `iterating'). The whole thing's actually wrapped up in several layers of classes and structs; I simplified a lot of this above since I assumed it wasn't important, but what's actually going on is the following:

Big templated container class I'm pushing stuff into, with irrelevant members snipped out. The console output I've included comes from the member function at the end of this block (sorry for the very long names):
code:
template< class TParam, class TPhiFunc >
    class EA2ParameterAndSkeletonArray {
        private:

            typedef ParamAndPointerToSkel< TParam > ParamPointerPair;
            typedef std::list< ParamPointerPair > ListOfParamPointerPairs;
            typedef std::vector< ListOfParamPointerPairs* > VectorOfPointersToListOfParamPointerPairs;
            ParamPointerPair principalParameter;
            VectorOfPointersToListOfParamPointerPairs parameterStore;
            typename SetOfPointersToPairs::iterator iterToPrincipal;
        public:
            EA2ParameterAndSkeletonArray ( const int maxNumberOfSegments );
            ~EA2ParameterAndSkeletonArray();
            void addParameter ( const TParam& param );
        };

template< class TParam, class TPhiFunc >
    void EA2ParameterAndSkeletonArray< TParam, TPhiFunc >::addParameter ( const TParam& param ) {

        //EA2Skeleton* newskel = new EA2Skeleton(numSkeletonSegments);
        
        ( * ( parameterStore.begin() ) )->push_back ( ParamPointerPair ( param,  new EA2Skeleton(numSkeletonSegments) ) );
        //debugging code
        //TODO: remove once bug is fixed
        std::cout << "adding pair to store. Parameter value: "<< (parameterStore.front())->back().parameter.K 
        << " Address of skeleton is " << (parameterStore.front())->back().pToSkel << std::endl;
        ++numParams;
        return;

        }
Templated container struct I'm pushing into the big class above (where it's typedeffed to ParamPointerPair):
code:
template <class TParam>
struct ParamAndPointerToSkel {
    TParam parameter;
    EA2Skeleton* pToSkel;
    ParamAndPointerToSkel() : pToSkel(0) {}
    ParamAndPointerToSkel ( TParam inpParam, int numSegments ) : 
     parameter ( inpParam ) {pToSkel = new EA2Skeleton ( numSegments );}
    ParamAndPointerToSkel ( TParam inpParam, EA2Skeleton* inpPskel) :
     parameter ( inpParam ) , pToSkel ( inpPskel ) {}
    ~ParamAndPointerToSkel() {delete pToSkel;}
    };
`parameter' struct that will form one of the template parameters. The member 'K' is the only one that really matters for this example.
code:
namespace logistic {
    class LogisticParam {
        public:
            double r;
            double K;

            static double beta;
	    LogisticParam() {}
            LogisticParam ( double rI, double KI ) : r ( rI ), K ( KI ) {}
	    LogisticParam(const LogisticParam& par) : r(par.r), K(par.K) {}
	    ~LogisticParam(){}
        };
    }
relevant part of test.cpp:
code:
int main(){

...

    EA2ParameterAndSkeletonArray< logistic::LogisticParam, logistic::Phi >* arrayPoint1 = 
    new EA2ParameterAndSkeletonArray< logistic::LogisticParam, logistic::Phi > ( 3 );

    //create a bunch of LogisticParams with varying values of K:
    typedef logistic::LogisticParam logParam;
    logParam param1 = logParam ( 0.3, 1 );
    logParam param2 = logParam ( 0.3, 2 );
    logParam param3 = logParam ( 0.3, 3 );
    logParam param5 = logParam ( 0.3, 5 );

    //push these LogisticParams
    arrayPoint1->addParameter ( param1 );
    arrayPoint1->addParameter ( param2 );
    arrayPoint1->addParameter ( param3 );
    arrayPoint1->addParameter ( param5 );

...

return 0;
}
console output (produced by the member function at the end of the first block of code):
code:
adding pair to store. Parameter value: 1 Address of skeleton is 0x61be90
adding pair to store. Parameter value: 2 Address of skeleton is 0x61be90
adding pair to store. Parameter value: 3 Address of skeleton is 0x61be90
adding pair to store. Parameter value: 5 Address of skeleton is 0x61be90
So it appears to be creating and adding the ParamAndPointerToSkel appropriately, but they point to the same block of memory each time.

edit: table breaking

DoctorTristan fucked around with this message at 17:47 on Jun 22, 2009

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