File: ISize.h

package info (click to toggle)
storm-lang 0.7.5-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 52,100 kB
  • sloc: ansic: 261,471; cpp: 140,438; sh: 14,891; perl: 9,846; python: 2,525; lisp: 2,504; asm: 860; makefile: 678; pascal: 70; java: 52; xml: 37; awk: 12
file content (75 lines) | stat: -rw-r--r-- 1,811 bytes parent folder | download | duplicates (3)
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
66
67
68
69
70
71
72
73
74
75
#pragma once
#include "Utils/Bitwise.h"

/**
 * Size assuming a specific max alignment. Used to implement "Size". "Size" is
 * preferred in other cases.
 */
template <nat maxAlign>
class ISize {
public:
	// Initialize to a specific size.
	ISize(nat size = 0) {
		assert((size & sizeMask) == size);
		assert((maxAlign & alignMaskLow) == maxAlign);

		this->size = size;
		// Align maximum of 'align' bytes.
		this->align = max(nat(1), min(maxAlign, size));
	}

	// Initialize to previously obtained values.
	ISize(nat size, nat align) : size(size), align(align) {
		assert((size & sizeMask) == size);
		assert((maxAlign & alignMaskLow) == maxAlign);
	}

	// Add another aligned size.
	ISize<maxAlign> &operator +=(const ISize &o) {
		// Update our alignment requirement.
		align = max(align, o.align);

		// Align and add.
		// Note: our alignment is not always important; consider the following example:
		// int, bool, bool, where the booleans do not have to be aligned to 4 bytes like
		// the int. If we had used 'align' instead of 'o.align' we would have aligned them
		// too strict.
		size = roundUp(size, o.align) + o.size;
		return *this;
	}

	// Multiply this by a positive constant.
	ISize<maxAlign> &operator *=(nat o) {
		if (o == 0) {
			size = 0;
		} else if (o == 1) {
			// Identity
		} else {
			nat more = (o - 1) * roundUp(size, align);
			size += more;
		}
		return *this;
	}


	// Data.
	struct {
		// Upper 4 bits used to indicate alignment
		nat align : 4;
		// lower 28 for size.
		nat size : 28;
	};

	// Constants.
	enum {
		alignMaskLow = 0x0000000F,
		alignMask    = 0xF0000000,
		sizeMask     = 0x0FFFFFFF,
	};
};


template <nat maxAlign>
wostream &operator <<(wostream &to, const ISize<maxAlign> &o) {
	return to << toHex(o.size, true) << L"(" << toHex(o.align, false) << L")";
}