less-than operator overloader for a long array

  • (2 Pages)
  • +
  • 1
  • 2

21 Replies - 560 Views - Last Post: 21 November 2012 - 08:25 AM Rate Topic: -----

#1 DJViking  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 25
  • Joined: 07-November 12

less-than operator overloader for a long array

Posted 19 November 2012 - 03:11 AM

My less-than operator overload does not work the way I have implemented it.

I have created a wrapper class around an oid array (which is actually an array of long elements).
This wrapper class contains a pointer to an oid and the length of the array.

I'm using this wrapper class as a key in a std::map. When calling at of find on this map it uses the less-than operator overloader for my wrapper.

Fetching from this map while all keys are of equal length goes fine:
const oid oid1[] = { 1,3,6,1,4,1,40850,1,3,1 };
const oid oid2[] = { 1,3,6,1,4,1,40850,1,3,2 };
const oid oid3[] = { 1,3,6,1,4,1,40850,1,3,3 };



Fetching from this map while keys have different length does not work The function at/find throws out_of_range exception.
const oid oid4[] = { 1,3,6,1,4,1,40850,1,3,1,9,1 };
const oid oid5[] = { 1,3,6,1,4,1,40850,1,3,1,9,2 };
const oid oid6[] = { 1,3,6,1,4,1,40850,1,3,1,9,3 };



My wrapper class: oid_wrapper.cpp
#ifndef OID_WRAPPER_H_
#define OID_WRAPPER_H_

#include <ostream>
#include <sstream>
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>

class oid_wrapper {
	friend std::ostream& operator<<(std::ostream& output, const oid_wrapper& wrapper);
public:
	oid_wrapper(const oid* _oid_value, int _oid_length) : oid_value(0), oid_length(_oid_length) {
		oid_value = snmp_duplicate_objid(_oid_value, oid_length);
	}

	const oid* get_oid() const { return oid_value; }
	const int& get_length() const { return oid_length; }

	/**
	 * copy operator overloader
	 */
	oid_wrapper& operator=(const oid_wrapper& wrapper) {
		oid_value = snmp_duplicate_objid(wrapper.get_oid(), wrapper.get_length());
		oid_length = wrapper.get_length();

		return *this;
	}

	/**
	 * equal operator overloader
	 */
	bool operator==(const oid_wrapper& rhs) const {
		const oid* rhs_oid = rhs.get_oid();
		const int rhs_length = rhs.get_length();

		if (netsnmp_oid_equals(oid_value, oid_length, rhs_oid, rhs_length) == 0) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * less-than operator overloader
	 */
	bool operator<(const oid_wrapper& rhs) const {
		const oid* rhs_oid = rhs.get_oid();
		const int rhs_length = rhs.get_length();

		bool retval = false;
		if (oid_length < rhs_length) { return true; }

		for (int i = 0; i < oid_length; i++) {
			if (oid_value[i] < rhs_oid[i]) { return true; }
		}

		return false;
    }

	const long getLastNumberInOid() const { return oid_value[oid_length - 1]; }

	bool operator!=(const oid_wrapper& rhs) { return !operator==(rhs); }
	bool operator>(const oid_wrapper& rhs) { return !operator<(rhs); }
	bool operator<=(const oid_wrapper& rhs) { return !operator>(rhs); }
	bool operator>=(const oid_wrapper& rhs) { return !operator<(rhs); }

private:
	const oid* oid_value;
	int oid_length;
};

/**
 * output operator overloader
 */
inline std::ostream& operator<<(std::ostream& output, const oid_wrapper& wrapper) {
	const oid* oid_value = wrapper.get_oid();
	int oid_length = wrapper.get_length();

	for(int i = 0; i < oid_length; i++) {
		output << oid_value[i];
		if (i != oid_length - 1) {
			output << ".";
		}
	}
	return output;
}

#endif /* OID_WRAPPER_H_ */




Is This A Good Question/Topic? 0
  • +

Replies To: less-than operator overloader for a long array

#2 DJViking  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 25
  • Joined: 07-November 12

Re: less-than operator overloader for a long array

Posted 19 November 2012 - 04:34 AM

It seems it was lacking the following piece of code:

if (oid_length > rhs_length) { return false; }

Was This Post Helpful? 0
  • +
  • -

#3 JackOfAllTrades  Icon User is offline

  • Saucy!
  • member icon

Reputation: 6058
  • View blog
  • Posts: 23,495
  • Joined: 23-August 08

Re: less-than operator overloader for a long array

Posted 19 November 2012 - 04:36 AM

if (oid_length < rhs_length) { return true; }

for (int i = 0; i < oid_length; i++) {
    if (oid_value[i] < rhs_oid[i]) { return true; }
}


OK, so if oid_length is 5, and rhs_length is 4, what's going to happen in your loop when you access rhs_oid[4], the upper bound of the oid_value array?
Was This Post Helpful? 0
  • +
  • -

#4 DJViking  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 25
  • Joined: 07-November 12

Re: less-than operator overloader for a long array

Posted 20 November 2012 - 01:41 AM

I added the line of code from post #2.

		if (oid_length < rhs_length) { return true; }
		if (oid_length > rhs_length) { return false; }

		for (int i = 0; i < oid_length; i++) {
			if (oid_value[i] < rhs_oid[i]) { return true; }
		}


Was This Post Helpful? 0
  • +
  • -

#5 DJViking  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 25
  • Joined: 07-November 12

Re: less-than operator overloader for a long array

Posted 20 November 2012 - 06:01 AM

Anyway. It did not quite work.

With the following test code, I add multiple oid_wrapper into a std::map.
It will output:
Run 1 Success
Run 2 Success
Run 3 Success
Run 4: 32
Run 5: 0
Run 6 Success
Run 7 Success

That meaning, at run4 it finds 32, but 100 was added. At run5 it finds 0 while 100 was added.

#include <iostream>
#include <ostream>
#include <string>
#include <map>
#include <stdexcept>

#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>

#include "oid_wrapper.h"

using namespace std;

int main(int argc, char **argv) {

	cout << "Testing first set of OID" << endl;
	const oid oid1[] = { 1,3,6,1,4,1,40850,1,3 };
	const oid_wrapper parent1 (oid1, 9);
	const oid_wrapper parent1_child1 (parent1, 40);
	const oid_wrapper parent1_child2 (parent1, 41);
	const oid_wrapper parent1_child3 (parent1, 42);
	const oid_wrapper parent1_child4 (parent1, 43);

	map<oid_wrapper, string> test;
	test.insert(make_pair(parent1_child1, "parent1_child1"));
	test.insert(make_pair(parent1_child2, "parent1_child2"));
	test.insert(make_pair(parent1_child3, "parent1_child3"));
	test.insert(make_pair(parent1_child4, "parent1_child4"));
	if (test.size() != 4) { cout << "FAIL" << endl; }
	cout << "Number of OID in list: " << test.size() << endl;

	const oid_wrapper parent11 (oid1, 9);
	const oid_wrapper parent1_child11 (parent11, 40);
	try {
		string teststring = test.at(parent1_child11);
		cout << "Success" << endl;
	} catch (out_of_range& e) {
		cout << "Failure" << endl;
	}

	const oid_wrapper parent1_child12 (parent11, 41);
	try {
		string teststring = test.at(parent1_child12);
		cout << "Success" << endl;
	} catch (out_of_range& e) {
		cout << "Failure" << endl;
	}

	const oid_wrapper parent1_child13 (parent11, 42);
	try {
		string teststring = test.at(parent1_child13);
		cout << "Success" << endl;
	} catch (out_of_range& e) {
		cout << "Failure" << endl;
	}

	const oid_wrapper parent1_child14 (parent11, 43);
	try {
		string teststring = test.at(parent1_child14);
		cout << "Success" << endl;
	} catch (out_of_range& e) {
		cout << "Failure" << endl;
	}

	cout << "Testing second set of OID" << endl;
	const oid oid2[] = { 1,3,6,1,4,1,40850,2,1,9,1 };
	const oid_wrapper parent2 (oid2, 11);
	const oid_wrapper parent2_child1 (parent2, 1);
	const oid_wrapper parent2_child2 (parent2, 2);
	const oid_wrapper parent2_child3 (parent2, 3);
	const oid_wrapper parent2_child4 (parent2, 4);

	test.insert(make_pair(parent2_child1, "parent2_child1"));
	test.insert(make_pair(parent2_child2, "parent2_child2"));
	test.insert(make_pair(parent2_child3, "parent2_child3"));
	test.insert(make_pair(parent2_child4, "parent2_child4"));
	if (test.size() != 8) { cout << "FAIL" << endl; }
	cout << "Number of OID in list: " << test.size() << endl;

	const oid_wrapper parent21 (oid2, 11);
	const oid_wrapper parent1_child21 (parent21, 1);
	try {
		string teststring = test.at(parent1_child21);
		cout << "Success" << endl;
	} catch (out_of_range& e) {
		cout << "Failure" << endl;
	}

	const oid_wrapper parent1_child22 (parent21, 2);
	try {
		string teststring = test.at(parent1_child22);
		cout << "Success" << endl;
	} catch (out_of_range& e) {
		cout << "Failure" << endl;
	}

	const oid_wrapper parent1_child23 (parent21, 3);
	try {
		string teststring = test.at(parent1_child23);
		cout << "Success" << endl;
	} catch (out_of_range& e) {
		cout << "Failure" << endl;
	}

	const oid_wrapper parent1_child24 (parent21, 4);
	try {
		string teststring = test.at(parent1_child24);
		cout << "Success" << endl;
	} catch (out_of_range& e) {
		cout << "Failure" << endl;
	}

	//#################################################

	//Adding 100 OIDs
	for (int i = 0; i < 100; i++) {
		const oid newoid[] = { 1,3,6,1,4,1,40850,2,1,9,1 };
		const oid_wrapper wrapper(newoid, 11, i);
		test.insert(make_pair(wrapper, "wrapper"));
	}

	//Query for the 100 added OIDs
	int run1 = 0;
	for (int i = 0; i < 100; i++) {
		const oid newoid[] = { 1,3,6,1,4,1,40850,2,1,9,1 };
		const oid_wrapper wrapper(newoid, 11, i);

		try {
			string teststring = test.at(wrapper);
			run1++;
		} catch (out_of_range& e) {
			//FAIL
		}
	}
	if (run1 == 100) { cout << "Run 1 Success" << endl; }
	else { cout << "Run 1: " << run1 << endl; }

	//#################################################

	//Adding 100 OIDs
	for (int i = 0; i < 100; i++) {
		const oid newoid[] = { 1,3,6,1,4,1,40850,1,3 };
		const oid_wrapper wrapper(newoid, 9, i);
		test.insert(make_pair(wrapper, "wrapper"));
	}

	//Query for the 100 added OIDs
	int run2 = 0;
	for (int i = 0; i < 100; i++) {
		const oid newoid[] = { 1,3,6,1,4,1,40850,1,3 };
		const oid_wrapper wrapper(newoid, 9, i);

		try {
			string teststring = test.at(wrapper);
			run2++;
		} catch (out_of_range& e) {
			//FAIL
		}
	}
	if (run2 == 100) { cout << "Run 2 Success" << endl; }
	else { cout << "Run 2: " << run2 << endl; }

	//#################################################

	//Adding 100 OIDs
	for (int i = 0; i < 10; i++) {
		const oid newoid[] = { 1,3,6,1,4,1,40850,2 };
		const oid_wrapper wrapper(newoid, 8, i);
		test.insert(make_pair(wrapper, "wrapper"));
	}

	//Query for the 100 added OIDs
	int run3 = 0;
	for (int i = 0; i < 10; i++) {
		const oid newoid[] = { 1,3,6,1,4,1,40850,2 };
		const oid_wrapper wrapper(newoid, 8, i);

		try {
			string teststring = test.at(wrapper);
			run3++;
		} catch (out_of_range& e) {
			//FAIL
		}
	}
	if (run3 == 10) { cout << "Run 3 Success" << endl; }
	else { cout << "Run 3: " << run3 << endl; }

	//#################################################

	//Adding 500 OIDs
	for (int i = 0; i < 100; i++) {
		const oid newoid[] = { 1,3,6,1,4,1,40850,2,2,5,1 };
		const oid_wrapper wrapper(newoid, 11, i);
		test.insert(make_pair(wrapper, "wrapper"));
	}

	//Query for the 500 added OIDs
	int run4 = 0;
	for (int i = 0; i < 100; i++) {
		const oid newoid[] = { 1,3,6,1,4,1,40850,2,2,5,1 };
		const oid_wrapper wrapper(newoid, 11, i);

		try {
			string teststring = test.at(wrapper);
			run4++;
		} catch (out_of_range& e) {
			//FAIL
		}
	}
	if (run4 == 100) { cout << "Run 4 Success" << endl; }
	else { cout << "Run 4: " << run4 << endl; }

	//#################################################

	//Adding 500 OIDs
	for (int i = 0; i < 100; i++) {
		const oid newoid[] = { 1,3,6,1,4,1,40850,2,3,5,2 };
		const oid_wrapper wrapper(newoid, 11, i);
		test.insert(make_pair(wrapper, "wrapper"));
	}

	//Query for the 500 added OIDs
	int run5 = 0;
	for (int i = 0; i < 100; i++) {
		const oid newoid[] = { 1,3,6,1,4,1,40850,2,3,5,2 };
		const oid_wrapper wrapper(newoid, 11, i);

		try {
			string teststring = test.at(wrapper);
			run5++;
		} catch (out_of_range& e) {
			//FAIL
		}
	}
	if (run5 == 100) { cout << "Run 5 Success" << endl; }
	else { cout << "Run 5: " << run5 << endl; }

	//#################################################

	//Adding 500 OIDs
	for (int i = 0; i < 100; i++) {
		const oid newoid[] = { 1,3,6,1,4,1,40850,2,2,5,2 };
		const oid_wrapper wrapper(newoid, 10, i);
		test.insert(make_pair(wrapper, "wrapper"));
	}

	//Query for the 500 added OIDs
	int run6 = 0;
	for (int i = 0; i < 100; i++) {
		const oid newoid[] = { 1,3,6,1,4,1,40850,2,2,5,2 };
		const oid_wrapper wrapper(newoid, 10, i);

		try {
			string teststring = test.at(wrapper);
			run6++;
		} catch (out_of_range& e) {
			//FAIL
		}
	}
	if (run6 == 100) { cout << "Run 6 Success" << endl; }
	else { cout << "Run 6: " << run6 << endl; }

	//#################################################

	//Adding 500 OIDs
	for (int i = 0; i < 100; i++) {
		const oid newoid[] = { 1,3,6,1,4,1,40850,2,5,2,3,5 };
		const oid_wrapper wrapper(newoid, 12, i);
		test.insert(make_pair(wrapper, "wrapper"));
	}

	//Query for the 500 added OIDs
	int run7 = 0;
	for (int i = 0; i < 100; i++) {
		const oid newoid[] = { 1,3,6,1,4,1,40850,2,5,2,3,5 };
		const oid_wrapper wrapper(newoid, 12, i);

		try {
			string teststring = test.at(wrapper);
			run7++;
		} catch (out_of_range& e) {
			//FAIL
		}
	}
	if (run7 == 100) { cout << "Run 7 Success" << endl; }
	else { cout << "Run 7: " << run7 << endl; }
}


Was This Post Helpful? 0
  • +
  • -

#6 JackOfAllTrades  Icon User is offline

  • Saucy!
  • member icon

Reputation: 6058
  • View blog
  • Posts: 23,495
  • Joined: 23-August 08

Re: less-than operator overloader for a long array

Posted 20 November 2012 - 06:25 AM

Is the header file in the original post your full, current implementation? I can't get it to compile with that, as you appear to be using constructors in your test file which do not exist in the implementation.

oid_test.cpp:19: error: no matching function for call to ‘oid_wrapper::oid_wrapper(const oid_wrapper&, int)’
oid_wrapper.h:12: note: candidates are: oid_wrapper::oid_wrapper(const oid*, int)
oid_wrapper.h:9: note:                 oid_wrapper::oid_wrapper(const oid_wrapper&)

Was This Post Helpful? 0
  • +
  • -

#7 DJViking  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 25
  • Joined: 07-November 12

Re: less-than operator overloader for a long array

Posted 20 November 2012 - 06:30 AM

To bad I cannot edit my post:

Anyway here are all my constructors for oid_wrapper.h

	template <size_t N> oid_wrapper(const oid (&array)[N]) : oid_value(array), oid_length(N) {}

	oid_wrapper(const oid* _oid_value, int _oid_length) : oid_value(0), oid_length(_oid_length) {
		oid_value = snmp_duplicate_objid(_oid_value, oid_length);

		/* code from snmp_duplicate_objid
		oid *returnOid;
		if (_oid_value != NULL && _length != 0) {
			returnOid = (oid *) malloc(_length * sizeof(oid));
			if (returnOid) {
				memcpy(returnOid, _oid_value, _length * sizeof(oid));
			}
		} else {
			returnOid = NULL;
		}

		oid_value = returnOid;
		*/
	}

	oid_wrapper(const oid* parent_oid, int _oid_length, const int assigned_value) : oid_value(0), oid_length(_oid_length) {
		oid* new_oid = new oid[oid_length + 1];
		memcpy(new_oid, parent_oid, oid_length * sizeof(oid));
		new_oid[oid_length++] = assigned_value;
		oid_value = new_oid;
	}

	oid_wrapper(const oid_wrapper _oid_wrapper, const int assigned_value) : oid_value(0), oid_length(0) {
		oid_length = _oid_wrapper.oid_length;
		const oid* parent_oid = _oid_wrapper.get_oid();

		oid* new_oid = new oid[oid_length + 1];
		memcpy(new_oid, parent_oid, oid_length * sizeof(oid));
		new_oid[oid_length++] = assigned_value;
		oid_value = new_oid;
	}


Was This Post Helpful? 0
  • +
  • -

#8 JackOfAllTrades  Icon User is offline

  • Saucy!
  • member icon

Reputation: 6058
  • View blog
  • Posts: 23,495
  • Joined: 23-August 08

Re: less-than operator overloader for a long array

Posted 20 November 2012 - 06:41 AM

Is there a reason you're not clearing your test map before each test? Because if I do that, all tests pass.
Was This Post Helpful? 0
  • +
  • -

#9 DJViking  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 25
  • Joined: 07-November 12

Re: less-than operator overloader for a long array

Posted 20 November 2012 - 06:44 AM

In my application I could have a map with over 4000 keys. So therefore I didn't want to clear the map in order to test for such a large map.
Was This Post Helpful? 0
  • +
  • -

#10 JackOfAllTrades  Icon User is offline

  • Saucy!
  • member icon

Reputation: 6058
  • View blog
  • Posts: 23,495
  • Joined: 23-August 08

Re: less-than operator overloader for a long array

Posted 20 November 2012 - 06:51 AM

OK, just making sure that was your intention. Without the clears I get the following results:

$ ./oid_test
Testing first set of OID
Number of OID in list: 4
Success
Success
Success
Success
Testing second set of OID
Number of OID in list: 8
Success
Success
Success
Success
Run 1: 94
Run 2: 95
Run 3 Success
Run 4: 26
Run 5: 0
Run 6 Success
Run 7 Success

Was This Post Helpful? 0
  • +
  • -

#11 DJViking  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 25
  • Joined: 07-November 12

Re: less-than operator overloader for a long array

Posted 20 November 2012 - 06:54 AM

Different for my run:
Testing first set of OID
Number of OID in list: 4
Success
Success
Success
Success
Testing second set of OID
Number of OID in list: 8
Success
Success
Success
Success
Run 1 Success
Run 2 Success
Run 3 Success
Run 4: 32
Run 5: 0
Run 6 Success
Run 7 Success

The other thing is: If I iterate over this map all elements are actually there. It is just the function std::map::at() that does not work properly. I suspect it has to do with a problem with my operator< overloader in oid_wrapper.
Was This Post Helpful? 0
  • +
  • -

#12 JackOfAllTrades  Icon User is offline

  • Saucy!
  • member icon

Reputation: 6058
  • View blog
  • Posts: 23,495
  • Joined: 23-August 08

Re: less-than operator overloader for a long array

Posted 20 November 2012 - 07:16 AM

It's been a while since I've done anything with maps, so I may be the wrong person to be looking at this, but what's interesting is that using the standard map accessor, like this:

string teststring = test[wrapper];


also yields complete success.

/me shrugs

EDIT: Oops, missed that part of your reply. The at() operator for map is new to me, and appears to perhaps be a GNU extension?

EDIT 2: Oh, at() is maybe C++ 11, and [] will add the key if it doesn't exist, rendering my test moot.

Sorry.

This post has been edited by JackOfAllTrades: 20 November 2012 - 07:19 AM

Was This Post Helpful? 0
  • +
  • -

#13 DJViking  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 25
  • Joined: 07-November 12

Re: less-than operator overloader for a long array

Posted 20 November 2012 - 07:18 AM

It looks like that function std::map::at() came with c++0x
Was This Post Helpful? 0
  • +
  • -

#14 jimblumberg  Icon User is offline

  • member icon


Reputation: 4017
  • View blog
  • Posts: 12,400
  • Joined: 25-December 09

Re: less-than operator overloader for a long array

Posted 20 November 2012 - 07:19 AM

Quote

The at() operator for map is new to me, and appears to perhaps be a GNU extension?

Nope, C++11 addition.

Jim

This post has been edited by jimblumberg: 20 November 2012 - 07:19 AM

Was This Post Helpful? 0
  • +
  • -

#15 DJViking  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 25
  • Joined: 07-November 12

Re: less-than operator overloader for a long array

Posted 20 November 2012 - 07:22 AM

However, I get the same problem while using std::map::find(Key).
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2