question about operators

I want to define a structure that acts much like a bitset object except that you define how many bits you need when it is created so it doesn't take up excess space, memory is an extreme issue in my case or I would use a vector<bool>, I can't have multiple structs that each take up 20 bytes before anything is added to them. What I don't know how to do is define the operators so that I could access it with a [] and assign with a = and directly reference the bit (I suppose I'll need to do it much the way bitset and vector bool do it, with a reference to some kind of object that acts like a bool but is actually a reference to the bit.) Does anyone know how to do this?
Override the allocator of the bitset, and you are done.
really... how do you do THAT
or are you saying that bitset already can be a set size, i'm not quite sure how to use it based on the article in here, it doesn't mention template arguments, and the compiler is bitching about it

--edit bitset<somenumber>, what does somenumber DO exactly, is it a number of bytes or bits? And does it actually have an effect on the amount of memory allocated to biset's internal bitfield?
Last edited on
Err, of course I am lying. I thought about vector and wrote bitset. You could define another allocator for vector, but using a bitset is simpler:

The template class bitset<N> describes an object that can store a sequence consisting of a fixed number of bits, N.
also, the object I'm going to use it in won't know what bounds to set for the number of bits until its actually constructed, can bitset handle that?
No, it can not. You can still define that allocator...
I think the sizeof(vector<bool>) returns 20 for its contents, this doesn't include things pointed to, only the variables it contains, so its too large anyway.
I think the sizeof(vector<bool>) returns 20 for its contents, this doesn't include things pointed to, only the variables it contains, so its too large anyway.

I would understand if you didn't want the default vectors allocation behaviour due to it's exponential growth. But if 20 bytes is too much overhead, you should be using another language.
Maybe I could do the following: (its not totally complete yet, but its complete enough to answer my question.)
If I use the following structs, if it use [] operator on a bitflags object it probably should construct a Bitref and return it, how do I ensure that the returned Bitref doesn't cause a memory leak once the operation using it completes?
say i have a bitflags named "bf" and I do something like bf[0]=1;
I probably shouldn't rely on the = operator to destroy the bitref, since you could technically use bf[0]; by itself on a line (does nothing but its still valid code), so how do I ensure its destruction?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
struct Bitref
{
	char * bits;
	char bi;
	Bitref(char * b, char BI)
	{
		bits=b;
		bi=BI;
	}
	struct Bitref & operator =(const struct Bitref &BC)
	{
		if(this==&BC){return *this;}
		(*bits)&=~((char)(1<<bi));
		(*bits)|=((*(BC.bits))&((char)(1<<bi)));
		return *this;
	}
	struct Bitref & operator =(unsigned short int i)
	{
		if(i!=0)
		{
			(*bits)|=(char)(1<<bi);
		}
		else
		{
			(*bits)&=~((char)(1<<bi));
		}
	}
};
typedef struct Bitref bitref;
struct Bitflags
{
	char * bits;
	Bitflags(unsigned short int Bits)
	{
		unsigned short int bytes=0,t=Bits;
		while(t>8)
		{
			t>>3;
			bytes++;
		}
		if(t){bytes++;}
		bits=new char[bytes];
	}
	void get(unsigned short int i)
	{
		
	}
	void set_ON(unsigned short int i)
	{
		
	}
	void set_OFF(unsigned short int i)
	{
		
	}
	struct Bitref& operator[](unsigned short int s)
	{
		
	}
	~Bitflags()
	{
		delete bits;
	}
};
typedef struct Bitflags bitflags;
if 20 bytes is too much overhead, you should be using another language.

It wouldn't be if I wasn't expecting to find so many matches and construct so many objects. This variable isn't going to be stored at the top of main, its going to be a member of a linked list node.
assuming I accept the 20 bytes, how would I overwrite the allocator?
I'm not going to write in one post what is usually coped with in a entire chapter of a book just concerned with the stl. However, some hints:
- most containers (all except bitstream, I think) take an allocator as template argument, with a default of std::allocator<T>
- the allocator implements (beside others) the functions 'pointer allocate(size_type n, allocator<void>::const_pointer hint = 0)' and 'deallocate(pointer p, size_type n)'
- If you inherit from 'std::allocator' and override these functions to return the pointer to a fixed-size (e.g. given in the (also overridden) constructor) (or free the memory, respectively), you should be done (i.e., you say in the constructor 'no more than 5 bytes' and the vector then says 'give me 10 bytes' (due to the fact that it allocates memory exponentially), you give it just 5 bytes. Of course, you have to be damn careful not to exceed these 5 bytes. Since the 5 more bytes would be initialized using the allocators placement-new, and the allocator also saves the ammount of allocated space (which is then only 5), this is no problem, since the placement-new should obey the ammount of bytes you say you have in the allocator.)
Beware: allocate and deallocate just (de-)allocate the memory. 'construct' and 'destroy' are used as 'placement-new' and -delete. This is important for exception safety issues.
So, if you want to do it, I reccomend a look at, e.g., "The C++ Programming Language" sect. 19.4 - Allocators. One of the "Exceptional C++" has a similar topic, I think (writing an own, exception-safe/neutral stack that was, I think, and it was done by a seperate class used mainly as 'allocator' if I'm not mistaken)
Topic archived. No new replies allowed.