Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Iterator equivalent in C++? (with code)

Tags:

java

c++

Hey all. A friend wrote up some Java code for me and I am easily able to convert it to C++ but I am very curious as to the equivalent for a Java iterator in C++. Here is the code and I would most likely want the data to returned into a vector. Any help is appreciated

public class RLEIterator
extends RegionIterator
{
    public int reg = 0;
    public int mode = 0;
    public int skip = 0;
        // mode is the number of IDs that are valid still (count down)
        // skip is used after we run out of mode IDs, and move forward
        //   The goal is, to always have a valid 'hasNext' state, after
        // an ID is read via 'next'. Thus, the initial search, and then
        // the reading forward if mode == 0, after the ID is found.
    public int i;

    public RLEIterator()
    {
        // Need to set up the skip of an initial part, so we can
        // correctly handle there not being anything, despite there
        // being data encoded.

        int comp;
        i = 0;

        while ((mode == 0) && (i<nearRLE.length))
        {
            // set up the next code
            comp = ((int)nearRLE[i]) & 0xff;

            if ((comp > 0) && (comp <= 0x3e))
            {
                // skip forward by comp;
                reg += comp;
                i++;
                mode = 0; // have to keep on reading
            }
            else if (comp == 0x3f)
            {
                // skip forward by the following 16 bit word;
                // second byte is hi-byte of the word
                reg += ((int)nearRLE[i+1]) & 0xff;
                reg += (((int)nearRLE[i+2]) & 0xff) << 8;

                i+=3;
            }
            else if (comp == 0xff)
            {
                // include the following WORD of regions
                mode = ((int)nearRLE[i+1]) & 0xff;
                mode += (((int)nearRLE[i+2]) & 0xff) << 8;
                i += 3;
            }
            else if ((comp >= 0xc0) && (comp <= 0xfe))
            {
                // comp - 0xc0 regions are nearby
                mode = comp - 0xc0;  // +1 perhaps?
                i++;
            }
            else if ((comp >= 0x40) && (comp <= 0x7f))
            {
                // skip bits 3-5 IDs and then include bits 0-2
                reg += (comp & 0x38) >> 3;
                mode = (comp & 0x7);
                i++;
            }
            else if ((comp >= 0x80) && (comp <= 0xbf))
            {
                // include IDs bits 3-5, then skip bits 0-2
                mode = (comp & 0x38) >> 3;
                skip = (comp & 0x7);
                i++;
            }
        }
    }

    public boolean hasNext()
    {
        // not at the end of the RLE, and not currently processing a
        // directive. (mode)
        return (mode > 0);
    }

    public int next()
    {
        int ret = -1;
        int comp;

        // sanity check first. Shouldn't truthfully get called if mode
        // isn't >0
        if (mode <= 0)
            return -1;

        ret = reg;
        reg++;
        mode--;

        if (mode == 0)
        {
            // skip forward
            reg += skip;
            skip = 0;

            while ((mode == 0) && (i<nearRLE.length))
            {
                // set up the next code
                comp = ((int)nearRLE[i]) & 0xff;

                if ((comp > 0) && (comp <= 0x3e))
                {
                    // skip forward by comp;
                    reg += comp;
                    i++;
                    mode = 0; // have to keep on reading
                }
                else if (comp == 0x3f)
                {
                    // skip forward by the following 16 bit word;
                    // second byte is hi-byte of the word
                    reg += ((int)nearRLE[i+1]) & 0xff;
                    reg += (((int)nearRLE[i+2]) & 0xff) << 8;

                    i+=3;
                }
                else if (comp == 0xff)
                {
                    // include the following WORD of regions
                    mode = ((int)nearRLE[i+1]) & 0xff;
                    mode += (((int)nearRLE[i+2]) & 0xff) << 8;
                    i += 3;
                }
                else if ((comp >= 0xc0) && (comp <= 0xfe))
                {
                    // comp - 0xc0 regions are nearby
                    mode = comp - 0xc0;  // +1 perhaps?
                    i++;
                }
                else if ((comp >= 0x40) && (comp <= 0x7f))
                {
                    // skip bits 3-5 IDs and then include bits 0-2
                    reg += (comp & 0x38) >> 3;
                    mode = (comp & 0x7);
                    i++;
                }
                else if ((comp >= 0x80) && (comp <= 0xbf))
                {
                    // include IDs bits 3-5, then skip bits 0-2
                    mode = (comp & 0x38) >> 3;
                    skip = (comp & 0x7);
                    i++;
                }
            }
        }

        return ret;
    }
}

Again, any help on how this would fit into the scheme of a single function (if possible) in C++ would be fantastic. Thanks!

like image 544
Satchmo Brown Avatar asked Oct 10 '22 20:10

Satchmo Brown


1 Answers

How familiar are you with C++ iterators? They are designed to look very much like pointers, so that given an iterator it:

++it

will increment the iterator (skip to the next element)

*it

will dereference the iterator (return a reference to the element it points to)

--it

will (if it is defined at all) decrement the iterator (go back to the previous element)

C++ iterators in general know nothing about the container they operate on. In particular, the way you check whether there are more elements left in the sequence is not to call HasNext on the iterator, but instead compare it against an iterator you know points to the end of the sequence. (or, strictly speaking, compare it to an element which points just past the end of the sequence.)

Beyond that, iterators need to define a few typedefs and other auxiliary stuff to help the compiler categorize and understand the iterator's capabilities.

The simplest way to define an iterator is to use the Boost.Iterator library's iterator_facade class, which implements nearly all of the plumbing for you. The library has excellent documentation, including a tutorial describing how to define your own iterator type.

If using Boost is an option, you should definitely go for that. Otherwise, the standard library has std::iterator which helps a bit as well (but, it is worth noting, is not mandatory -- iterators can be defined perfectly validly without deriving from this class)

I'm sorry I don't have a complete example written out, but I'm in a bit of a hurry right now. (And, if you're able to use Boost, it'd be a waste of time to go through the trouble of defining an example iterator from scratch). Hopefully the above is enough to get you started.

like image 119
jalf Avatar answered Oct 14 '22 00:10

jalf