best/worst code youve seen?

Pages: 123
today i finished writing a working version of my lexer (thank you @albatross, @James2250, @Lachlane) and as i went over it i realized that it was very messy. not poorly written, but not my best. it could also be cleaned up and refactored a lot too. anyways, it got me to thinking... what was the best or worst code youve seen?
Hands down best I've seen:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
template<typename Iter>
auto slide(Iter begin, Iter end, Iter target) -> std::pair<Iter,Iter>
{
    if (target < begin) return std::make_pair( target, std::rotate(target, begin, end) );
    if (end < target) return std::make_pair( std::rotate( begin, end, target ), target );
    return std::make_pair( begin, end );
}
 
template<typename Iter, typename Pred>
auto gather(Iter begin, Iter end, Iter target, Pred predicate) -> std::pair<Iter,Iter>
{
    auto start = std::stable_partition( begin, target, std::not1(predicate) );
    auto finish = std::stable_partition( target, end, predicate );
    return std::make_pair(start, finish);
}

For those wondering where these functions came from: https://www.youtube.com/watch?v=lX5tfRdkoY0
Last edited on
Iterator hell ^ LOL
I'm still curious where this C++ programmers love for iterators is coming from.
Last edited on
Iterators are great. Did you know Java has them? Java iterators are underpowered though.
@ Lachlan Easton: no offense but they're yucky.

Apparently the language doesn't even allow you to write the proper return type in front, where it belongs. Also if you write auto then why do you need to later write std::pair<Iter,Iter> as well? Yucky yuck.

Back on topic, one of my favorite pieces of C++ code:

1
2
3
4
5
6
template<class ForwardIt>
void selection_sort(ForwardIt begin, ForwardIt end)
{
    for (ForwardIt i = begin; i != end; ++i)
        std::iter_swap(i, std::min_element(i, end));
}


Edit: off-topic again:

rapidcoder wrote:
I'm still curious where this C++ programmers love for iterators is coming from.

I believe it comes from the fact that Iterators allow Containers and Algorithms to be combined like Lego. *tongue-in-cheek*
Last edited on
no offense but they're yucky.

None taken, they're not my functions.
return type in front, where it belongs

And I personally believe types should be on the RHS, but it's really a style choice, perhaps I've been reading too much Sutter http://herbsutter.com/2013/08/12/gotw-94-solution-aaa-style-almost-always-auto/.
I don't know where you're getting "yucky" from :P
Edit: I'm actually surprised that that's the part that made you flinch, 'cuz there's a better way to return from those functions to clean it up(with uniform initialisation) https://gist.github.com/LBEaston/43cfa0961437f76c2ad3
Last edited on

Iterators are great


Iterators are useful, but enough useful to base the whole standard library on them.


I believe it comes from the fact that Iterators allow Containers and Algorithms to be combined like Lego. *tongue-in-cheek*


Only some algorithms. Some algorithms require several passes over data or random access, and then iterator concept does not fit naturally. And it breaks totally for parallel algorithms (but this is not a problem, as long as the standard library does not offer anything here)

Last edited on
Some algorithms require several passes over data or random access, and then iterator concept does not fit naturally.

I'm having trouble seeing how o_O
And it breaks totally for parallel algorithms

Do you have any resources explaining why this is? What alternatives are there?
closed account (10X9216C)
rabidcoder wrote:
And it breaks totally for parallel algorithms (but this is not a problem, as long as the standard library does not offer anything here)

Breaking news, a single design pattern isn't a one size fits all.

CatFish wrote:
Also if you write auto then why do you need to later write std::pair<Iter,Iter> as well?

Putting it on the right hand side puts it in scope of the function.

1
2
3
4
5
6
7
8
9
10
11
class SomeClassName
{
    struct SomeOtherName;

    SomeOtherName foo();

};

auto SomeClassName::foo() -> SomeOtherName { }
// vs
SomeClassName::SomeOtherName SomeClassName::foo() { } 

Lachlan Easton wrote:
I'm having trouble seeing how o_O

I am unsure how to word my thoughts, so I'll just paste the code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <algorithm>
#include <iostream>
#include <list>

int main()
{
    std::list<int> li{ 2, 30, -29, 30, 10, 11, -100 };

    std::sort(li.begin(), li.end());

    for (int i : li)
        std::cout << i << ' ';

    std::cout << std::endl;
}

That's less a limitation of iterators than it is a limitation of lists.
incidentally, the 70+ old algorithms that were parallelized and all new parallel algorithms in the TS (reduce, inclusive_scan, exclusive_scan) use iterators.
Last edited on
Lachlan Easton wrote:
That's less a limitation of iterators than it is a limitation of lists.

And by extension, it's a limitation of list iterators.
The example shows how iterators cannot always separate the container from the algorithm. QED?

myesolar wrote:
Putting it on the right hand side puts it in scope of the function.

I thought the technical reason has to do with Iter being a dependent name, or something. I admit that I didn't try compiling the code.

But the point of my question was implying that auto should be enough by itself once used, as below, without the noise of ->pair<>:

1
2
3
4
5
template<typename Iter>
auto slide(Iter begin, Iter end, Iter target)
{
    // ...
}


Breaking news, a single design pattern isn't a one size fits all.


True. And C++ used this single pattern as the main design pattern of all the container library, forcing every concept that is not really an iterator be iterator. They had to overload iterator meaning to allow for random-access iterators or bidirectional iterators. Ugly as hell. Random-access iterator is used for the "random access" part, not for the "iterator" part. A side effect is that now you have to remember which iterator types work with which containers and it is even not clearly visible in the API. And you also have to give a pair of iterators everywhere where you really mean passing a collection (even Java iterators don't have this limitation - one iterator is enough).

Well-designed libraries provide iterators as part of them and then allow to perform *some* algorithms that are natural on iterators like filtering or mapping, but not sorting. Therefore you know the iterator is just an iterator and the algorithm on iterator will iterate data once. Algorithms that need other types of containers, just... guess what... get other collections as arguments. E.g. quick-sorting makes sense on random-access sequences and k-means makes sense on iterable things (iterable = something that can create an iterator to do multiple passes).

Last edited on
rapidcoder wrote:
C++ used this single pattern as the main design pattern of all the container library, forcing every concept that is not really an iterator be iterator.
Guess what Java does with classes ;p
My favorite piece of code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
float Q_rsqrt( float number )
{
	long i;
	float x2, y;
	const float threehalfs = 1.5F;
 
	x2 = number * 0.5F;
	y  = number;
	i  = * ( long * ) &y;                       // evil floating point bit level hacking
	i  = 0x5f3759df - ( i >> 1 );               // what the fuck?
	y  = * ( float * ) &i;
	y  = y * ( threehalfs - ( x2 * y * y ) );   // 1st iteration
//      y  = y * ( threehalfs - ( x2 * y * y ) );   // 2nd iteration, this can be removed
 
	return y;
}


From Quake 3

http://en.wikipedia.org/wiki/Fast_inverse_square_root
closed account (10X9216C)
True. And C++ used this single pattern as the main design pattern of all the container library, forcing every concept that is not really an iterator be iterator.

Indeed it's not perfect, indeed it could be better, but it works for what's needed. If it fails, there is usually a boost library somewhere that compensates for it. Stop moving from argument to argument, we all know you hate C++ senselessly, as most of us hate Java senselessly, leave your C++ senselessness for your Java forarms.
Who told you I hate C++ more than I hate Java? This is C++ forum so we're discussing ugly code in C++. If it was a Java forum, we'd discuss ugly code in Java.
closed account (10X9216C)
Who told you I hate C++ more than I hate Java?

You did?

This is C++ forum so we're discussing ugly code in C++

So why do you keep bringing up Java? Stop trying to deflect.
Maybe he brings up bad C++ code in Java forums.

Anyways to add on the iterator discussion, I honestly have been lacking on using them until recently. I usually used to just write my own STL implementation until I realized how useless it was.
Pages: 123