Check-in [0a2b15c728]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:merged trunk into descriptor
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | descriptor
Files: files | file ages | folders
SHA1:0a2b15c72872d0c3bb9eb567eb7e26a657c613b3
User & Date: maxi 2018-11-13 06:32:31
Context
2018-11-13
06:39
Added trunk's greeter check-in: 8e1bed5819 user: maxi tags: descriptor
06:32
merged trunk into descriptor check-in: 0a2b15c728 user: maxi tags: descriptor
2018-11-12
19:04
bugs fixed check-in: b3b5eb5f08 user: Alisad tags: descriptor
12:56
Changed more C-Style Casts check-in: 5f36b15924 user: maxi tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to Makefile.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
..
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68

SRC:=                      \
	$(wildcard src/*.s)\
	$(wildcard src/*.cpp)\
	$(wildcard src/buffers/*)\
	$(wildcard src/libk/*)\
	$(wildcard src/memory/*)\
	$(wildcard src/termutils/*)\
	$(wildcard src/asm_shims/*)\
	$(wildcard src/tests/*)\
	$(wildcard src/drivers/*)\
	$(wildcard src/disk_structure/*)\
	$(wildcard src/acpi/*)\
	$(wildcard src/smp/*)\
	$(wildcard src/interrupts/*)\

OBJECTS := $(SRC:%.cpp=$(OBJ_DIR)/%.cpp.o)
................................................................................
	@mkdir -p $(@D)
	$(CXX) -T linker.ld -nostdlib $(CXXFLAGS) $(INCLUDE) -o $(APP_DIR)/kernel.bin $(OBJECTS) -lgcc

clean:
	rm build -rf

image: kernel
	grub-file --is-x86-multiboot $(APP_DIR)/kernel.bin
	mkdir -p $(APP_DIR)/isodir/boot/grub
	cp $(APP_DIR)/kernel.bin $(APP_DIR)/isodir/boot/kernel.bin
	cp grub.cfg $(APP_DIR)/isodir/boot/grub/grub.cfg
	grub-mkrescue -o $(APP_DIR)/clinl.iso $(APP_DIR)/isodir

test: image
	qemu-system-x86_64 -hda $(APP_DIR)/clinl.iso

debug_run:
	qemu-system-i386 --cpu host -S -s -d guest_errors -cdrom $(APP_DIR)/clinl.iso &> $(BUILD)/klog &
	sleep 3
	gdb -w --eval-command="target remote localhost:1234" $(APP_DIR)/kernel.bin








|
|







 







<



|





|



>
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
..
48
49
50
51
52
53
54

55
56
57
58
59
60
61
62
63
64
65
66
67
68
SRC:=                      \
	$(wildcard src/*.s)\
	$(wildcard src/*.cpp)\
	$(wildcard src/buffers/*)\
	$(wildcard src/libk/*)\
	$(wildcard src/memory/*)\
	$(wildcard src/termutils/*)\
	$(wildcard src/asm_shims/*.)\
	$(wildcard src/tests/*.cpp)\
	$(wildcard src/drivers/*)\
	$(wildcard src/disk_structure/*)\
	$(wildcard src/acpi/*)\
	$(wildcard src/smp/*)\
	$(wildcard src/interrupts/*)\

OBJECTS := $(SRC:%.cpp=$(OBJ_DIR)/%.cpp.o)
................................................................................
	@mkdir -p $(@D)
	$(CXX) -T linker.ld -nostdlib $(CXXFLAGS) $(INCLUDE) -o $(APP_DIR)/kernel.bin $(OBJECTS) -lgcc

clean:
	rm build -rf

image: kernel

	mkdir -p $(APP_DIR)/isodir/boot/grub
	cp $(APP_DIR)/kernel.bin $(APP_DIR)/isodir/boot/kernel.bin
	cp grub.cfg $(APP_DIR)/isodir/boot/grub/grub.cfg
	grub2-mkrescue -o $(APP_DIR)/clinl.iso $(APP_DIR)/isodir

test: image
	qemu-system-x86_64 -hda $(APP_DIR)/clinl.iso

debug_run:
	qemu-system-i386 -S -s -d guest_errors -cdrom $(APP_DIR)/clinl.iso &
	sleep 3
	gdb -w --eval-command="target remote localhost:1234" $(APP_DIR)/kernel.bin


Added include/acpi/acpi_utils.hpp.




































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#pragma once
#include "structures.h"
#include "libk/string.h"
#include "buffers/string_view"

namespace ACPI
{
namespace UTILS
{
template <class T>
inline bool correct_table_checksum(T *ptr)
{
    uint8_t check = 0;
    uint8_t *bptr = reinterpret_cast<uint8_t *>(ptr);
    for (int i = 0; i < sizeof(T); ++i, ++bptr)
        check += *bptr;
    return check == 0;
}

inline bool check_for_correct_rsdp(sign_8_type *ptr)
{
    struct SDT::RSDP *rsdp_ptr = reinterpret_cast<SDT::RSDP*> (ptr);
    constexpr char *sig = "RSD PTR ";

    if (memcmp(ptr, sig, 8) == 0)
        if (correct_table_checksum(rsdp_ptr))
            return true;
    return false;
}

inline bool is_rsdp_v2(char revision)
{
    return revision != 0;
}

inline SDT::RSDP *find_lower_rsdp()
{
    ksdk::buffer<sign_8_type> search_buf{reinterpret_cast<sign_8_type *>(0x000E0000),
                                         reinterpret_cast<sign_8_type *>(0x00100000)};
    for (auto it = search_buf.begin(); it != search_buf.end(); ++it)
        if (check_for_correct_rsdp(&*it))
            return reinterpret_cast<SDT::RSDP *>(&*it);
}

inline SDT::RSDP *find_upper_rsdp()
{
    ksdk::buffer<sign_8_type> ebda_search_buf{reinterpret_cast<sign_8_type *>(0x40E), reinterpret_cast<sign_8_type *>(0x40E + 1025)};

    for (auto it = ebda_search_buf.begin(); it != ebda_search_buf.end(); ++it)
        if (check_for_correct_rsdp(&*it))
            return reinterpret_cast<SDT::RSDP *>(&*it);
}

inline SDT::RSDP *find_rsdp()
{
    SDT::RSDP *ptr1 = find_lower_rsdp();
    if (ptr1 != nullptr)
        return ptr1;
    SDT::RSDP *ptr2 = find_upper_rsdp();
    if (ptr2 != nullptr)
        return ptr2;
    return nullptr;
}

} // namespace UTILS
} // namespace ACPI

Changes to include/acpi/structures.h.

12
13
14
15
16
17
18









19
20
21
22
23
24
25
..
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
76
77
78
79
...
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
...
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
struct sign_4_type
{
  char sign[4];
};

namespace SDT
{










struct RSDP
{
  char Signature[8];
  uint8_t Checksum;
  char OEMID[6];
  uint8_t Revision;
................................................................................
  RSDP firstPart;

  uint32_t Length;
  uint64_t XsdtAddress;
  uint8_t ExtendedChecksum, reserved[3];
} __attribute__((packed));

struct ACPISDTHeader
{
  char Signature[4];
  uint32_t Length;
  uint8_t Revision, Checksum;
  char OEMID[6];
  char OEMTableID[8];
  uint32_t OEMRevision, CreatorID, CreatorRevision;
} __attribute__((packed));

typedef ACPISDTHeader generic_sdt;

struct BER
{ //Boot error Region
  uint32_t BlockStatus, RawDataOffset, RawDataLenght, DataLength, ErrorSeverity;
  uint8_t GenericErrorData[1]; //treated as array for now, will be handled by a wrapper class later
} __attribute__((packed));

struct BERT
{
  ACPISDTHeader h;
  uint32_t BootErrorRegionLength;
  uint64_t BooErrorRegion;
} __attribute__((packed));

struct CPEP
{
  ACPISDTHeader h;
  uint32_t Reserved;             //MUST be 0
  uint8_t ProcessorStructure[1]; //handled by a wrapper class
} __attribute__((packed));

struct DSDT
{
  ACPISDTHeader h;
  uint8_t DefinitionBlock[1]; //handled by wrapper class -- length-headersize bytes of AML code
} __attribute__((packed));

struct GENERIC_MADT_ENTRY
{
  uint8_t EntryType, RecordLength;
} __attribute__((packed));
................................................................................
  uint32_t GICID;
  uint64_t PhysicalBaseAdress;
  uint32_t SystemVectorBase, Reserved_2;
} __attribute__((packed));

struct MADT
{
  ACPISDTHeader h;
  uint32_t LocalApicAddress, Flags;
  uint8_t Entries[1];
} __attribute__((packed));

struct RSDT
{
  ACPISDTHeader h;
  uint32_t PointerToOtherSDT[1];
} __attribute__((packed));

struct XSDT
{
  ACPISDTHeader h;
  uint64_t PointerToOtherSDT[1];
} __attribute__((packed));

struct GenericAddressStructure
{
  uint8_t AddressSpace, BitWidth, BitOffset, AccessSize;
  uint64_t Address;
................................................................................
  uint8_t Reserved_1[3];
  uint32_t OSPMFlags;
  uint8_t Reserved_2[24];
};

struct FADT
{
  ACPISDTHeader h;
  uint32_t FirmwareCtrl; //pointer to FACS
  uint32_t Dsdt;         // pointer to DSDT

  // field used in ACPI 1.0; no longer in use, for compatibility only
  uint8_t Reserved, PreferredPowerManagementProfile;
  uint16_t SCI_Interrupt;
  uint32_t SMI_CommandPort;






>
>
>
>
>
>
>
>
>







 







<
<
<
<
<
<
<
<
<
<
<
<








|






|






|







 







|






|





|







 







|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
..
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
76
...
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
...
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
struct sign_4_type
{
  char sign[4];
};

namespace SDT
{
struct generic_sdt
{
  char Signature[4];
  uint32_t Length;
  uint8_t Revision, Checksum;
  char OEMID[6];
  char OEMTableID[8];
  uint32_t OEMRevision, CreatorID, CreatorRevision;
} __attribute__((packed));

struct RSDP
{
  char Signature[8];
  uint8_t Checksum;
  char OEMID[6];
  uint8_t Revision;
................................................................................
  RSDP firstPart;

  uint32_t Length;
  uint64_t XsdtAddress;
  uint8_t ExtendedChecksum, reserved[3];
} __attribute__((packed));













struct BER
{ //Boot error Region
  uint32_t BlockStatus, RawDataOffset, RawDataLenght, DataLength, ErrorSeverity;
  uint8_t GenericErrorData[1]; //treated as array for now, will be handled by a wrapper class later
} __attribute__((packed));

struct BERT
{
  generic_sdt h;
  uint32_t BootErrorRegionLength;
  uint64_t BooErrorRegion;
} __attribute__((packed));

struct CPEP
{
  generic_sdt h;
  uint32_t Reserved;             //MUST be 0
  uint8_t ProcessorStructure[1]; //handled by a wrapper class
} __attribute__((packed));

struct DSDT
{
  generic_sdt h;
  uint8_t DefinitionBlock[1]; //handled by wrapper class -- length-headersize bytes of AML code
} __attribute__((packed));

struct GENERIC_MADT_ENTRY
{
  uint8_t EntryType, RecordLength;
} __attribute__((packed));
................................................................................
  uint32_t GICID;
  uint64_t PhysicalBaseAdress;
  uint32_t SystemVectorBase, Reserved_2;
} __attribute__((packed));

struct MADT
{
  generic_sdt h;
  uint32_t LocalApicAddress, Flags;
  uint8_t Entries[1];
} __attribute__((packed));

struct RSDT
{
  generic_sdt h;
  uint32_t PointerToOtherSDT[1];
} __attribute__((packed));

struct XSDT
{
  generic_sdt h;
  uint64_t PointerToOtherSDT[1];
} __attribute__((packed));

struct GenericAddressStructure
{
  uint8_t AddressSpace, BitWidth, BitOffset, AccessSize;
  uint64_t Address;
................................................................................
  uint8_t Reserved_1[3];
  uint32_t OSPMFlags;
  uint8_t Reserved_2[24];
};

struct FADT
{
  generic_sdt h;
  uint32_t FirmwareCtrl; //pointer to FACS
  uint32_t Dsdt;         // pointer to DSDT

  // field used in ACPI 1.0; no longer in use, for compatibility only
  uint8_t Reserved, PreferredPowerManagementProfile;
  uint16_t SCI_Interrupt;
  uint32_t SMI_CommandPort;

Changes to include/acpi/wrappers.h.

1

2
3
4
5
6

7

8
9
10

11
12
13
14
15
16
17
..
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






76
77
78
79
80
#pragma once

#include "asm_shims/shims.h"
#include "termutils/terminal.h"
#include "libk/string.h"
#include "buffers/string_view"
#include "kstd/iterator.hpp"

#include "structures.h"


namespace ACPI
{

struct found_tables
{
    bool APIC = false;

    bool all_found()
    {
        if (APIC)
................................................................................
    }
};

struct madt_wrapper
{
    size_t offset = 0;
    SDT::MADT *madt_ptr;

    madt_wrapper(SDT::MADT *ptr);
    SDT::GENERIC_MADT_ENTRY *get_entry(size_t index);
    SDT::GENERIC_MADT_ENTRY *get_next_entry();
    SDT::GENERIC_MADT_ENTRY *get_next_entry_if();
    bool is_out_of_bounds(size_t offset);
    void reset_entry_pointer();
    SDT::GENERIC_MADT_ENTRY *get_first_entry_with(uint8_t type); //first entry with a specific entry type
};

struct bert_wrapper
{
#pragma message "Implement BERT - Wrapper"
};

struct dsdt_wrapper
{
    SDT::DSDT *stored;
    dsdt_wrapper(SDT::DSDT *other);

    ksdk::string_view getCode();
};

class fadt_wrapper
{
  public:
    SDT::FADT *stored;
    fadt_wrapper(SDT::FADT *);

    SDT::DSDT *get_dsdt();
    void enable_acpi();
    void disable_acpi();
    //add other functions when needed by the general program
};

struct sdt_wrapper
{
  public:
    found_tables ft;
    int acpi_version;
    int number_tables;
    SDT::RSDP *rsdp_ptr;
    SDT::RSDP20 *rsdp_20_ptr;
    SDT::RSDT *rsdt_ptr; //use ONLY in ACPI 1 systems
    SDT::XSDT *xsdt_ptr; //to be used, if not null (similar to rsdt, but bigger adressing space)

    fadt_wrapper *fadt;
    madt_wrapper *madt; //wrapper for that table



    sdt_wrapper();






    SDT::generic_sdt *get_table(size_t index);
    void find_structures();
    dsdt_wrapper *get_dsdt();
};
} // namespace ACPI
>

<
<


>

>



>







 







|



|


|











>








>



|










|
|
>
|
<
>
>


>
>
>
>
>
>


<


1
2
3


4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
..
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
76
77

78
79
80
81
82
83
84
85
86
87
88
89

90
91
#pragma once
#include "acpi_utils.hpp"
#include "asm_shims/shims.h"


#include "buffers/string_view"
#include "kstd/iterator.hpp"
#include "libk/string.h"
#include "structures.h"
#include "termutils/terminal.h"

namespace ACPI
{

struct found_tables
{
    bool APIC = false;

    bool all_found()
    {
        if (APIC)
................................................................................
    }
};

struct madt_wrapper
{
    size_t offset = 0;
    SDT::MADT *madt_ptr;
    madt_wrapper();
    madt_wrapper(SDT::MADT *ptr);
    SDT::GENERIC_MADT_ENTRY *get_entry(size_t index);
    SDT::GENERIC_MADT_ENTRY *get_next_entry();
    SDT::GENERIC_MADT_ENTRY *get_current_entry();
    bool is_out_of_bounds(size_t offset);
    void reset_entry_pointer();
    SDT::GENERIC_MADT_ENTRY *get_first_entry_with(uint8_t type); // first entry with a specific entry type
};

struct bert_wrapper
{
#pragma message "Implement BERT - Wrapper"
};

struct dsdt_wrapper
{
    SDT::DSDT *stored;
    dsdt_wrapper(SDT::DSDT *other);
    dsdt_wrapper();
    ksdk::string_view getCode();
};

class fadt_wrapper
{
  public:
    SDT::FADT *stored;
    fadt_wrapper(SDT::FADT *);
    fadt_wrapper();
    SDT::DSDT *get_dsdt();
    void enable_acpi();
    void disable_acpi();
    // add other functions when needed by the general program
};

struct sdt_wrapper
{
  public:
    found_tables ft;
    int acpi_version;
    int number_tables;
    SDT::RSDP *rsdp_ptr;
    SDT::RSDP20 *rsdp_20_ptr;
    SDT::RSDT *rsdt_ptr; // use ONLY in ACPI 1 systems
    SDT::XSDT *xsdt_ptr; // to be used, if not null (similar to rsdt, but bigger
                         // adressing space)
    fadt_wrapper fadt;

    madt_wrapper madt; // wrapper for that table
    dsdt_wrapper dsdt;

    sdt_wrapper();
    inline void set_rsdp(void *);
    void set_rsdt(uint32_t ptr);
    void set_xsdt(uint32_t ptr);
    void set_dsdt();
    void set_fadt();
    int get_number_of_tables();
    SDT::generic_sdt *get_table(size_t index);
    void find_structures();

};
} // namespace ACPI

Changes to include/algorithms/copy.hpp.

1
2
3
4
5
6
7
8
9
10
11
#pragma once

template<class it_src, class it_dest>
it_dest copy(it_src src_b, it_src src_e,it_dest dest_b)
{
	auto it=src_b;
	auto wit=dest_b;
	for(;it!=src_e;++it,++wit)
		*wit=*it;
	return wit;
}

|
|

|
|
|
|
|

1
2
3
4
5
6
7
8
9
10
11
#pragma once

template <class it_src, class it_dest>
it_dest copy(it_src src_b, it_src src_e, it_dest dest_b)
{
    auto it = src_b;
    auto wit = dest_b;
    for (; it != src_e; ++it, ++wit)
        *wit = *it;
    return wit;
}

Changes to include/buffers/buffer.hpp.

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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127

#pragma once
#include <stddef.h>
#include "buffers/container.hpp"

namespace __internals{


	template<typename T>
	T& ref(T& n)
	{
		return n;
	}

	template<class T>
	struct r_op_iterator
	{
		r_op_iterator(T* in):it(in){}
		T* it;
		auto operator++()
		{
			return it--;
		}
		auto operator++(int)
		{
			return --it;
		}
		auto operator--()
		{
			return it--;
		}
		auto operator--(int)
		{
			return --it;
		}
		T& operator*()
		{
			return *it;
		}
		T& operator[](const size_t idx)
		{
			return *(it-idx);
		}
		auto operator==(const r_op_iterator& rhs)
		{
			return it==rhs.it;
		}
		auto operator!=(const r_op_iterator& rhs)
		{
			return it!=rhs.it;
		}
		auto operator<=(const r_op_iterator& rhs)
		{
			return (rhs.it<=it);
		}
		auto operator>=(const r_op_iterator& rhs)
		{
			return (rhs.it>=it);
		}
		auto operator<(const r_op_iterator& rhs)
		{
			return (rhs.it<it);
		}
		auto operator>(const r_op_iterator& rhs)
		{
			return (rhs.it>it);
		}
	};

}

namespace ksdk{

	template<typename T>
	class buffer : public typed_container<T>
	{
	protected:
		T* _buffer;
		size_t _size;

	public:
		constexpr buffer(T* b, T* e)
		:_buffer(b)
		,_size(e-b)
		{
		}

		constexpr buffer()
		:_buffer(nullptr)
		,_size(0)
		{
		}

		constexpr buffer(T* b, size_t sz)
		:_buffer(b)
		,_size(sz)
		{
		}

		size_t size()
		{
			return _size;
		}

		T* begin()
		{
			return _buffer;
		}

		T* end()
		{
			return _buffer+_size;
		}

		__internals::r_op_iterator<T> rbegin()
		{
			return __internals::r_op_iterator<T>(_buffer-1+_size);
		}

		__internals::r_op_iterator<T> rend()
		{
			return __internals::r_op_iterator<T>(_buffer-1);
		}

		T& operator[](size_t idx)
		{
			return _buffer[idx];
		}

	};
}




|
|
>
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
<
|
>
|
|
|
|
|
|

|
|
|
<
|
|

|
|
<
|
|

|
|
<
|
|

|
|
|
|

|
|
|
|

|
|
|
|

|
|
|
|

|
|
|
|

|
|
|
|
<
|
<
>
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
76
77
78
79
80
81

82
83
84
85
86

87
88
89
90
91

92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123

124

125
#pragma once
#include <stddef.h>
#include "buffers/container.hpp"

namespace internals
{

template <typename T>
T &ref(T &n)
{
	return n;
}

template <class T>
struct r_op_iterator
{
	r_op_iterator(T *in) : it(in) {}
	T *it;
	auto operator++()
	{
		return it--;
	}
	auto operator++(int)
	{
		return --it;
	}
	auto operator--()
	{
		return it--;
	}
	auto operator--(int)
	{
		return --it;
	}
	T &operator*()
	{
		return *it;
	}
	T &operator[](const size_t idx)
	{
		return *(it - idx);
	}
	auto operator==(const r_op_iterator &rhs)
	{
		return it == rhs.it;
	}
	auto operator!=(const r_op_iterator &rhs)
	{
		return it != rhs.it;
	}
	auto operator<=(const r_op_iterator &rhs)
	{
		return (rhs.it <= it);
	}
	auto operator>=(const r_op_iterator &rhs)
	{
		return (rhs.it >= it);
	}
	auto operator<(const r_op_iterator &rhs)
	{
		return (rhs.it < it);
	}
	auto operator>(const r_op_iterator &rhs)
	{
		return (rhs.it > it);
	}
};
} // namespace internals


namespace ksdk
{
template <typename T>
class buffer
{
  protected:
	T *_buffer;
	size_t _size;

  public:
	constexpr buffer(T *begin, T *end)
		: _buffer(begin), _size(end - begin)

	{
	}

	constexpr buffer()
		: _buffer(nullptr), _size(0)

	{
	}

	constexpr buffer(T *b, size_t sz)
		: _buffer(b), _size(sz)

	{
	}

	size_t size()
	{
		return _size;
	}

	T *begin()
	{
		return _buffer;
	}

	T *end()
	{
		return _buffer + _size;
	}

	internals::r_op_iterator<T> rbegin()
	{
		return internals::r_op_iterator<T>(_buffer - 1 + _size);
	}

	internals::r_op_iterator<T> rend()
	{
		return internals::r_op_iterator<T>(_buffer - 1);
	}

	T &operator[](size_t idx)
	{
		return _buffer[idx];
	}

};

} // namespace ksdk

Changes to include/buffers/container.hpp.

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
#pragma once
#include <stddef.h>

inline void* operator new(size_t, void* empl)
{
	return empl;
}

namespace __internals{
	/* Enable_if implementation */
	template<bool b, class T = void>
	struct enable_if{};

	template<class T>
	struct enable_if<true,T>{
		typedef T type;
	};

	/* Enable_if helper implementation */
	template<bool b, class T = void>
	using enable_if_t = typename enable_if<b,T>::type;

	/* static_assert implementaion for comparing integers */
	template<bool b, typename t = enable_if_t<b>>
	class check{

	};
}

namespace ksdk{
	class container
	{
	public:
		size_t size();
	};

	template<class T>
	class typed_container : public container
	{

	};
}


|



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
1
2
3
4
5
6
7



































#pragma once
#include <stddef.h>

inline void *operator new(size_t, void *empl)
{
	return empl;
}



































Changes to include/buffers/sosa_tree.hpp.

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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377













378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399

400
401
402
403
404
405
406
407
408

409

410
411
412
413
414
415

416

417
418
419
420
421
422

#pragma once
#include "buffers/buffer.hpp"
#include "libk/memory.h"
#include "libk/string.h"

namespace ksdk
{
	namespace __internals
	{
		template<class T>
		bool less(T lhs, T rhs)
		{
			return lhs<rhs;
		}
		template<class T>
		bool equals(T lhs, T rhs)
		{
			return lhs==rhs;
		}
		template<class T>
		bool max(T lhs, T rhs)
		{
			return lhs<rhs?rhs:lhs;
		}
		template<class T>
		void swap(T& a, T& b)
		{
			char buffer[sizeof(T)];
			memcpy(buffer,&a,sizeof(T));
			memcpy(&a,&b,sizeof(T));
			memcpy(&b,buffer,sizeof(T));
		}

	}


	template<class T, bool(less)(const T, const T) = __internals::less, bool(equ)(const T, const T) = __internals::equals >
	class sosa_tree : public ksdk::typed_container<T>
	{
	public:
		template<class _T>
		struct node
		{
			int balance;
			bool set;
			_T elem;
		};
	private:
		size_t max_size;
		size_t byte_size;
		size_t size;
		ksdk::buffer<node<T> > data;

		/* pos is 1-indexed */
		constexpr size_t pos_to_parent(const size_t pos) const
		{
			if(pos!=1)
				return (pos ^ (pos & 1))>>1;
			else
				return 0;
		}

		/* pos is 1-indexed */
		constexpr size_t pos_to_left(const size_t pos) const
		{
			return pos<<1;
		}

		/* pos is 1-indexed */
		constexpr size_t pos_to_right(const size_t pos) const
		{
			return 1+(pos<<1);
		}

		/* pos is 1-indexed */
		constexpr bool pos_is_left(const size_t pos) const
		{
			return (pos&1)^1;
		}

		/* pos is 1-indexed */
		constexpr bool pos_is_right(const size_t pos) const
		{
			return pos&1;
		}

		/* pos is 1-indexed */
		constexpr size_t pos_to_uncle(size_t pos) const
		{
			auto parent=pos_to_parent(pos);
			auto grandfather=pos_to_parent(parent);
			auto side=parent&1;
			return side+(grandfather<<1);
		}

		void swap(const size_t pa, const size_t pb)
		{
			if(!data[pa-1].set && !data[pb-1].set)
				return;
			__internals::swap(data[pa-1],data[pb-1]);
			if(data[pa-1].set || data[pb-1].set)
			{
				swap(pos_to_left(pa),pos_to_left(pb));
				swap(pos_to_right(pa),pos_to_right(pb));
			}
		}

		T shift_lift_r(const size_t pos)
		{
			if(data[pos_to_right(pos)-1].set)
			{
				__internals::swap(data[pos_to_right(pos)-1],data[pos-1]);
				shift_lift_r(pos_to_right(pos));
			}
		}

		T shift_lift_l(size_t pos)
		{
			if(data[pos_to_left(pos)-1].set)
			{
				__internals::swap(data[pos_to_left(pos)-1],data[pos-1]);
				shift_lift_l(pos_to_left(pos));
			}
		}

		void shift_drop_r(const size_t pos)
		{
			if(data[pos_to_right(pos)-1].set)
				shift_drop_r(pos_to_right(pos));
			__internals::swap(data[pos_to_right(pos)-1],data[pos-1]);
		}

		void shift_drop_l(const size_t pos)
		{
			if(data[pos_to_left(pos)-1].set)
				shift_drop_l(pos_to_left(pos));
			__internals::swap(data[pos_to_left(pos)-1],data[pos-1]);
		}

		void drop_r(size_t pos)
		{
			if(!data[pos-1].set)
			{
				__internals::swap(data[pos-1],data[pos_to_parent(pos)-1]);
				swap(data[pos_to_left(pos_to_parent(pos))-1], data[pos-1]);
			}
			else
			{
				drop_r(pos_to_right(pos));
				__internals::swap(data[pos-1],data[pos_to_parent(pos)-1]);
				swap(data[pos_to_left(pos_to_parent(pos))-1], data[pos-1]);
			}
		}

		void drop_l(size_t pos)
		{
			if(!data[pos-1].set)
			{
				__internals::swap(data[pos-1],data[pos_to_parent(pos)-1]);
				swap(data[pos_to_right(pos_to_parent(pos))-1], data[pos-1]);
			}
			else
			{
				drop_l(pos_to_left(pos));
				__internals::swap(data[pos-1],data[pos_to_parent(pos)-1]);
				swap(data[pos_to_right(pos_to_parent(pos))-1], data[pos-1]);
			}
		}

		int update_balance(const size_t pos)
		{
			if(!data[pos-1].set)
			{
				return 0;
			}
			else
			{
				int l,r;
				l=update_balance(pos_to_left(pos));
				r=update_balance(pos_to_right(pos));
				data[pos-1].balance=r-l;
				return __internals::max(l,r);
			}
		}

		void rotate_l(const size_t pos)
		{
			shift_drop_l(pos);
			shift_lift_r(pos);
			update_balance(pos);
		}

		void rotate_r(const size_t pos)
		{
			shift_drop_r(pos);
			shift_lift_l(pos);
			update_balance(pos);
		}

		void rotate_rl(const size_t pos)
		{
			shift_drop_r(pos_to_right(pos));
			shift_lift_l(pos_to_right(pos));
			shift_drop_l(pos);
			shift_lift_r(pos);
			update_balance(pos);
		}

		void rotate_lr(const size_t pos)
		{
			shift_drop_l(pos_to_left(pos));
			shift_lift_r(pos_to_left(pos));
			shift_drop_r(pos);
			shift_lift_l(pos);
			update_balance(pos);
		}

		void move_to_pos (const size_t pos, const size_t dest) {
			data [dest] = data [pos];
			data[pos].set = false;
			data[pos].~T();
			if (data[pos_to_left (pos)].set) {
				move_to_pos (pos_to_left (pos), pos_to_left (dest));
			}
			if (data[pos_to_right (pos)].set) {
				move_to_pos (pos_to_right (pos), pos_to_right (dest));
			}
 		}

		char number_of_childs(const size_t pos) { 
			return data[pos_to_left(pos)-1].set+data[pos_to_right(pos)-1].set;
		}

		void rebalance_over_pos(size_t pos, int sign=1)
		{
			auto child=pos;
			for(auto trace=pos_to_parent(pos);trace!=0;trace=pos_to_parent(trace))
			{
				data[trace-1].balance+=(pos_is_right(child)-pos_is_left(child))*sign;
				if(data[trace-1].balance>1 || data[trace-1].balance<-1)
				{
					if(pos_is_right(child))
					{
						if (data[trace-1].balance > 0) {
							if (data[child-1].balance < 0)
								rotate_rl(trace);
							else
								rotate_l(trace);
						} else {
							if (data[trace-1].balance < 0) {
								data[trace-1].balance = 0;
								break;
							}
							data[trace-1].balance = +1;
							continue;
						}
					}else{
						if (data[trace-1].balance < 0) {
							if (data[child-1].balance > 0)
								rotate_lr(trace);
							else
								rotate_r(trace);
						} else {
							if (data[trace-1].balance > 0) {
								data[trace-1].balance = 0;
								break;
							}
							data[trace-1].balance = -1;
							continue;
						}
					}
				}
				child=trace;
			}
		}

	public:
		sosa_tree(size_t capacity_order)
		:max_size(1<<capacity_order)
		,byte_size(max_size*sizeof(node<T>))
		,size(0)
		,data((node<T>*)malloc(byte_size),max_size)
		{
			memset((void*)data.begin(),0,byte_size);
		}

		~sosa_tree()
		{
			free(data.begin());
		}

		ksdk::buffer<node<T> > buffer()
		{
			return data;
		}

		struct sosa_tree_iterator{
			size_t pos;
			sosa_tree<T,less,equ>* root;
			T& operator*()
			{
				return root->data[pos-1].elem;
			}
			sosa_tree_iterator& operator++()
			{
				if(pos==0)
				{
					pos=1;
					while(root->data[root->pos_to_left(pos)-1].set)
					{
						pos=root->pos_to_left(pos);
					}
					return *this;
				}
				if(root->data[root->pos_to_right(pos)-1].set)
				{
					pos=root->pos_to_right(pos);
					while(root->data[root->pos_to_left(pos)-1].set)
					{
						pos=root->pos_to_left(pos);
					}
				}
				else
				{
					while(root->pos_is_right(pos))
					{
						pos=root->pos_to_parent(pos);
					}
					pos=root->pos_to_parent(pos);
				}
				return *this;
			}
			sosa_tree_iterator operator++(int)
			{
				sosa_tree_iterator tmp=&this;
				this->operator++();
				return tmp;
			}
		};

		sosa_tree_iterator find(const T& val)
		{
			size_t pos = 1;
			while(data[pos-1].set)
			{
				if(equ(data[pos-1].elem,val)) [[unlikely]]
				{
					return sosa_tree_iterator{pos,this};
				}
				if(less(data[pos-1].elem,val))
				{
					pos=pos_to_right(pos);
				}
				else
				{
					pos=pos_to_left(pos);
				}
			}
			return sosa_tree_iterator{0,this};
		}

		void insert(const T& val)
		{
			size++;
			size_t pos=1;
			if(data[0].set) [[likely]]
			{
				do
				{
					if(equ(data[pos-1].elem,val))
					{
						data[pos-1].elem=val;
						return;
					}
					else if (less(data[pos-1].elem,val))
					{
						pos=pos_to_right(pos);













					}
					else
					{
						pos=pos_to_left(pos);
					}

				}while(data[pos-1].set);
				data[pos-1].elem=val;
				data[pos-1].set=true;
				//rebalance_over_pos(pos);
				return;

			}
			else
			{
				data[0].set=true;
				data[0].elem=val;
				return;
			}
		}

		bool remove (const size_t pos) {

			data[pos-1].set = false;
			data[pos-1].elem.~T();
			auto forward = 0;
			if(data[pos-1].balance>0)
			{
				shift_lift_r(pos);
				forward = pos_to_right(pos);
				for(;data[forward-1].set;forward = pos_to_right(pos))
				{}

			}

			else
			{
				shift_lift_l(pos);
				forward = pos_to_left(pos);
				for(;data[forward-1].set;forward = pos_to_left(pos))
				{}

			}

			rebalance_over_pos(forward,-1);
			size--;
			return true;
		}
	};
}




|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>



|


|
|
|


<
<
|

|
|


|

|
>
|
|
|
|
|
|
|
|
<
>

>
|
|
|
|
|
<
>

>
|
|
|
|
|
<
>
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401


402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419

420
421
422
423
424
425
426
427

428
429
430
431
432
433
434
435

436
#pragma once
#include "buffers/buffer.hpp"
#include "libk/memory.h"
#include "libk/string.h"
#include "kstd/utility.hpp"
#include "kstd/algorithm.hpp"
#include "kstd/functional.hpp"

namespace ksdk
{
namespace internals
{
template <class T>
bool less(T lhs, T rhs)
{
	return lhs < rhs;
}
template <class T>
bool equals(T lhs, T rhs)
{
	return lhs == rhs;
}
template <class T>
bool max(T lhs, T rhs)
{
	return lhs < rhs ? rhs : lhs;
}

} // namespace internals

template <class T, bool(less)(const T, const T) = internals::less, bool(equ)(const T, const T) = internals::equals>
class sosa_tree
{
  public:
	template <class _T>
	struct node
	{
		int balance;
		bool set;
		_T elem;
	};

  private:
	size_t max_size;
	size_t byte_size;
	size_t size;
	ksdk::buffer<node<T>> data;

	/* pos is 1-indexed */
	constexpr size_t pos_to_parent(const size_t pos) const
	{
		if (pos != 1)
			return (pos ^ (pos & 1)) >> 1;
		else
			return 0;
	}

	/* pos is 1-indexed */
	constexpr size_t pos_to_left(const size_t pos) const
	{
		return pos << 1;
	}

	/* pos is 1-indexed */
	constexpr size_t pos_to_right(const size_t pos) const
	{
		return 1 + (pos << 1);
	}

	/* pos is 1-indexed */
	constexpr bool pos_is_left(const size_t pos) const
	{
		return (pos & 1) ^ 1;
	}

	/* pos is 1-indexed */
	constexpr bool pos_is_right(const size_t pos) const
	{
		return pos & 1;
	}

	/* pos is 1-indexed */
	constexpr size_t pos_to_uncle(size_t pos) const
	{
		auto parent = pos_to_parent(pos);
		auto grandfather = pos_to_parent(parent);
		auto side = parent & 1;
		return side + (grandfather << 1);
	}

	void swap(const size_t pa, const size_t pb)
	{
		if (!data[pa - 1].set && !data[pb - 1].set)
			return;
		kstd::swap(data[pa - 1], data[pb - 1]);
		if (data[pa - 1].set || data[pb - 1].set)
		{
			swap(pos_to_left(pa), pos_to_left(pb));
			swap(pos_to_right(pa), pos_to_right(pb));
		}
	}

	T shift_lift_r(const size_t pos)
	{
		if (data[pos_to_right(pos) - 1].set)
		{
			kstd::swap(data[pos_to_right(pos) - 1], data[pos - 1]);
			shift_lift_r(pos_to_right(pos));
		}
	}

	T shift_lift_l(size_t pos)
	{
		if (data[pos_to_left(pos) - 1].set)
		{
			kstd::swap(data[pos_to_left(pos) - 1], data[pos - 1]);
			shift_lift_l(pos_to_left(pos));
		}
	}

	void shift_drop_r(const size_t pos)
	{
		if (data[pos_to_right(pos) - 1].set)
			shift_drop_r(pos_to_right(pos));
		kstd::swap(data[pos_to_right(pos) - 1], data[pos - 1]);
	}

	void shift_drop_l(const size_t pos)
	{
		if (data[pos_to_left(pos) - 1].set)
			shift_drop_l(pos_to_left(pos));
		kstd::swap(data[pos_to_left(pos) - 1], data[pos - 1]);
	}

	void drop_r(size_t pos)
	{
		if (!data[pos - 1].set)
		{
			kstd::swap(data[pos - 1], data[pos_to_parent(pos) - 1]);
			swap(data[pos_to_left(pos_to_parent(pos)) - 1], data[pos - 1]);
		}
		else
		{
			drop_r(pos_to_right(pos));
			kstd::swap(data[pos - 1], data[pos_to_parent(pos) - 1]);
			swap(data[pos_to_left(pos_to_parent(pos)) - 1], data[pos - 1]);
		}
	}

	void drop_l(size_t pos)
	{
		if (!data[pos - 1].set)
		{
			kstd::swap(data[pos - 1], data[pos_to_parent(pos) - 1]);
			swap(data[pos_to_right(pos_to_parent(pos)) - 1], data[pos - 1]);
		}
		else
		{
			drop_l(pos_to_left(pos));
			kstd::swap(data[pos - 1], data[pos_to_parent(pos) - 1]);
			swap(data[pos_to_right(pos_to_parent(pos)) - 1], data[pos - 1]);
		}
	}

	int update_balance(const size_t pos)
	{
		if (!data[pos - 1].set)
		{
			return 0;
		}
		else
		{
			int l, r;
			l = update_balance(pos_to_left(pos));
			r = update_balance(pos_to_right(pos));
			data[pos - 1].balance = r - l;
			return internals::max(l, r);
		}
	}

	void rotate_l(const size_t pos)
	{
		shift_drop_l(pos);
		shift_lift_r(pos);
		update_balance(pos);
	}

	void rotate_r(const size_t pos)
	{
		shift_drop_r(pos);
		shift_lift_l(pos);
		update_balance(pos);
	}

	void rotate_rl(const size_t pos)
	{
		shift_drop_r(pos_to_right(pos));
		shift_lift_l(pos_to_right(pos));
		shift_drop_l(pos);
		shift_lift_r(pos);
		update_balance(pos);
	}

	void rotate_lr(const size_t pos)
	{
		shift_drop_l(pos_to_left(pos));
		shift_lift_r(pos_to_left(pos));
		shift_drop_r(pos);
		shift_lift_l(pos);
		update_balance(pos);
	}

	void move_to_pos(const size_t pos, const size_t dest)
	{
		data[dest] = data[pos];
		data[pos].set = false;
		data[pos].~T();
		if (data[pos_to_left(pos)].set)
		{
			move_to_pos(pos_to_left(pos), pos_to_left(dest));
		}
		if (data[pos_to_right(pos)].set)
		{
			move_to_pos(pos_to_right(pos), pos_to_right(dest));
		}
	}

	char number_of_childs(const size_t pos)
	{
		return data[pos_to_left(pos) - 1].set + data[pos_to_right(pos) - 1].set;
	}

	inline void rebalance_right_node(size_t child, size_t &trace)
	{
		if (data[trace - 1].balance > 0)
		{
			if (data[child - 1].balance < 0)
				rotate_rl(trace);
			else
				rotate_l(trace);
		}
		else
		{
			if (data[trace - 1].balance < 0)
			{
				data[trace - 1].balance = 0;
				trace = 0;
			}
			data[trace - 1].balance = +1;
		}
	}

	inline void rebalance_left_node(size_t child, size_t &trace)
	{
		if (data[trace - 1].balance < 0)
		{
			if (data[child - 1].balance > 0)
				rotate_lr(trace);
			else
				rotate_r(trace);
		}
		else
		{
			if (data[trace - 1].balance > 0)
			{
				data[trace - 1].balance = 0;
				trace = 0;
			}
			data[trace - 1].balance = -1;
		}
	}

	inline bool needs_rebalancing(size_t trace)
	{
		return data[trace - 1].balance > 1 || data[trace - 1].balance < -1;
	}

	void rebalance_over_pos(size_t pos, int sign = 1)
	{
		size_t child = pos;
		for (size_t trace = pos_to_parent(pos); trace != 0; trace = pos_to_parent(trace))
		{
			data[trace - 1].balance += (pos_is_right(child) - pos_is_left(child)) * sign;
			if (needs_rebalancing(trace))
				if (pos_is_right(child))
					rebalance_right_node(child, trace);
				else
					rebalance_left_node(child, trace);
			child = trace;
		}
	}

  public:
	sosa_tree(size_t capacity_order)
		: max_size(1 << capacity_order), byte_size(max_size * sizeof(node<T>)), size(0), data((node<T> *)malloc(byte_size), max_size)
	{
		memset((void *)data.begin(), 0, byte_size);
	}

	~sosa_tree()
	{
		free(data.begin());
	}

	ksdk::buffer<node<T>> buffer()
	{
		return data;
	}

	struct sosa_tree_iterator
	{
		size_t pos;
		sosa_tree<T, less, equ> *root;
		T &operator*()
		{
			return root->data[pos - 1].elem;
		}
		sosa_tree_iterator &operator++()
		{
			if (pos == 0)
			{
				pos = 1;
				while (root->data[root->pos_to_left(pos) - 1].set)
				{
					pos = root->pos_to_left(pos);
				}
				return *this;
			}
			if (root->data[root->pos_to_right(pos) - 1].set)
			{
				pos = root->pos_to_right(pos);
				while (root->data[root->pos_to_left(pos) - 1].set)
				{
					pos = root->pos_to_left(pos);
				}
			}
			else
			{
				while (root->pos_is_right(pos))
				{
					pos = root->pos_to_parent(pos);
				}
				pos = root->pos_to_parent(pos);
			}
			return *this;
		}
		sosa_tree_iterator operator++(int)
		{
			sosa_tree_iterator tmp = &this;
			this->operator++();
			return tmp;
		}
	};

	sosa_tree_iterator find(const T &val)
	{
		size_t pos = 1;
		while (data[pos - 1].set)
		{
			if (equ(data[pos - 1].elem, val))
				[[unlikely]] {
					return sosa_tree_iterator{pos, this};
				} else if (less(data[pos - 1].elem, val))
				{
					pos = pos_to_right(pos);
				}
			else
			{
				pos = pos_to_left(pos);
			}
		}
		return sosa_tree_iterator{0, this};
	}

	void insert(const T &val)
	{
		size++;
		size_t pos = 1;
		if (data[0].set)
			[[likely]] {
				do
				{
					if (equ(data[pos - 1].elem, val))
					{
						data[pos - 1].elem = val;
						return;
					}
					else if (less(data[pos - 1].elem, val))
					{
						pos = pos_to_right(pos);
					}
					else
					{
						pos = pos_to_left(pos);
					}

				} while (data[pos - 1].set);
				data[pos - 1].elem = val;
				data[pos - 1].set = true;
				//rebalance_over_pos(pos);
				return;


			} else
			{
				data[0].set = true;
				data[0].elem = val;
				return;
			}
	}

	bool remove(const size_t pos)
	{
		data[pos - 1].set = false;
		data[pos - 1].elem.~T();
		auto forward = 0;
		if (data[pos - 1].balance > 0)
		{
			shift_lift_r(pos);
			forward = pos_to_right(pos);
			for (; data[forward - 1].set; forward = pos_to_right(pos))

			{
			}
		}
		else
		{
			shift_lift_l(pos);
			forward = pos_to_left(pos);
			for (; data[forward - 1].set; forward = pos_to_left(pos))

			{
			}
		}
		rebalance_over_pos(forward, -1);
		size--;
		return true;
	}
};

} // namespace ksdk

Changes to include/buffers/string_view.

1
2
3
4
5

6
7
8

9

10
11
12
13
14

15
16
17
18
#pragma once
#include "buffers/buffer.hpp"
#include "libk/string.h"

namespace ksdk{

using string_view = buffer<char>;

inline bool operator== (string_view rhs, string_view lhs) {

    if (rhs.size() != lhs.size()) {

        return false;
    }
    return memcmp (rhs.begin(), lhs.begin(), rhs.size()) == 0;
}
inline bool operator!= (string_view rhs, string_view lhs) {

    return !(rhs == lhs);
}

}



|
>


|
>
|
>


|

|
>



|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#pragma once
#include "buffers/buffer.hpp"
#include "libk/string.h"

namespace ksdk
{
using string_view = buffer<char>;

inline bool operator==(string_view rhs, string_view lhs)
{
    if (rhs.size() != lhs.size())
    {
        return false;
    }
    return memcmp(rhs.begin(), lhs.begin(), rhs.size()) == 0;
}
inline bool operator!=(string_view rhs, string_view lhs)
{
    return !(rhs == lhs);
}

} // namespace ksdk

Changes to include/buffers/vga_buffer.h.

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

#pragma once
#include "buffers/buffer.hpp"
#include <stdint.h>

namespace VGA
{

	/* Hardware text mode color constants. */
	enum class color : uint8_t {

		BLACK = 0,
		BLUE = 1,
		GREEN = 2,
		CYAN = 3,
		RED = 4,
		MAGENTA = 5,
		BROWN = 6,
		LIGHT_GREY = 7,
		DARK_GREY = 8,
		LIGHT_BLUE = 9,
		LIGHT_GREEN = 10,
		LIGHT_CYAN = 11,
		LIGHT_RED = 12,
		LIGHT_MAGENTA = 13,
		LIGHT_BROWN = 14,
		WHITE = 15,
	};

	struct color_mode
	{
		uint8_t v;
		constexpr color_mode(const uint8_t _v=(uint8_t)color::WHITE):v(_v){};
	} __attribute__((packed));

	constexpr inline color_mode make_color_mode(color fg, color bg=color::BLACK)
	{
		return ((uint8_t)fg | (uint8_t)bg << 4);
	}


	/* Hardware text mode character */
	struct character {

		constexpr character(char ch = ' ', color fg = color::WHITE, color bg = color::BLACK)
		:c(ch)

		,color(make_color_mode(fg,bg))
		{}

		constexpr character(char ch, color_mode tcolor)
		:c(ch)
		,color(tcolor)
		{}

		char c;
		color_mode color;
	} __attribute__((packed));



	void initialize();

	extern ksdk::buffer<char> buffer;
	extern ksdk::buffer<character> text_buffer;
	extern size_t TEXT_WIDTH;
	extern size_t TEXT_HEIGHT;
	extern size_t text_cursor;
	extern color_mode text_color;


}







|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|

|
|
|
|

<
|
|
>
|
<
>
|
<

|
<
<
<

|
|
|

<
<
<
<
|
|
|
|
|
|
>
>
|
>
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
#pragma once
#include "buffers/buffer.hpp"
#include <stdint.h>

namespace VGA
{

/* Hardware text mode color constants. */
enum class color : uint8_t
{
    BLACK = 0,
    BLUE = 1,
    GREEN = 2,
    CYAN = 3,
    RED = 4,
    MAGENTA = 5,
    BROWN = 6,
    LIGHT_GREY = 7,
    DARK_GREY = 8,
    LIGHT_BLUE = 9,
    LIGHT_GREEN = 10,
    LIGHT_CYAN = 11,
    LIGHT_RED = 12,
    LIGHT_MAGENTA = 13,
    LIGHT_BROWN = 14,
    WHITE = 15,
};

struct color_mode
{
    uint8_t v;
    constexpr color_mode(const uint8_t _v = (uint8_t)color::WHITE) : v(_v){};
} __attribute__((packed));

constexpr inline color_mode make_color_mode(color fg, color bg = color::BLACK)
{
    return ((uint8_t)fg | (uint8_t)bg << 4);
}


/* Hardware text mode character */
struct character
{
    constexpr character(char ch = ' ', color fg = color::WHITE,

                        color bg = color::BLACK)
        : c(ch), color(make_color_mode(fg, bg)) {}


    constexpr character(char ch, color_mode tcolor) : c(ch), color(tcolor) {}




    char c;
    color_mode color;
} __attribute__((packed));





extern ksdk::buffer<char> buffer;
extern ksdk::buffer<character> text_buffer;
extern size_t TEXT_WIDTH;
extern size_t TEXT_HEIGHT;
extern size_t text_cursor;
extern color_mode text_color;
void initialize();
void empty_vga_buffer();

} // namespace VGA

Changes to include/interrupts/pic_wrapper.h.

1
2



3
4

5




























6
#pragma once




namespace INT
{ //not to be confused with the datatype int lol






























} // namespace INT

>
>
>


>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

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
#pragma once

#include "kstd/utility.hpp"
#include "asm_shims/shims.h"

namespace INT
{ //not to be confused with the datatype int lol
namespace PICS
{

struct PIC_PORTS
{
  uint16_t command;
  uint16_t data;
}; // namespace INT_COMPstructPIC_PORTS

class PIC_8259
{
public:
  PIC_8259(bool, int);
  void disable();
  void remap();
  void end_interrupt();

private:
  bool type; //slave or master
  PIC_PORTS ports;
};
} // namespace PICS

class pic_wrapper
{
public:
  pic_wrapper(int, int);

  //kstd::pair<PICS::PIC_8259, PICS::PIC_8259> pics;
};
} // namespace INT

Changes to include/kstd/algorithm.hpp.

1

2
3
4
5
6
7
8
#pragma once

#include "cstdlib.hpp"

namespace kstd
{
template <class FwdIt>
FwdIt adjacent_find(FwdIt first, FwdIt last)
{
>







1
2
3
4
5
6
7
8
9
#pragma once
#include "iterator.hpp"
#include "cstdlib.hpp"

namespace kstd
{
template <class FwdIt>
FwdIt adjacent_find(FwdIt first, FwdIt last)
{

Changes to include/kstd/array.hpp.

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

76
77
78

79
80
81

82
83
84

85
86
87

88
89
90

91
92
93
94

95
96
97

98
99
100

101
102
103

104
105
106

107
108
109

110

111
112
113
114
115
116

117
118
119

120
121
122

123
124
125
126






127
128
129
130
131
132
133


134

135

136
137
138
139
140
141
142


143
144
145
146


147

148

149
150
151
152
153
154
155


156

157

158
159
160
161
162
163
164


165
166
167
168


169
170
171
172

173
174
175
176

177
178
179
180

181
182
183
184

185
186
187
188

#pragma once
#include "iterator.hpp"

namespace kstd {

	template<class T, size_t N> 
		struct array;

	template<class T, size_t N>
		struct array_iterator {

			typedef array_iterator self_type;
			typedef array<T, N> value_type;
			typedef array<T, N>& reference;
			typedef array<T, N>* pointer;
			typedef forward_iterator_tag iterator_category;
			typedef size_t difference_type;
			array_iterator (array<T, N>& other, size_t position) {

				content = other.content;
				content += position;
			}
			self_type operator++ () {

				self_type* i = this;
				content++;
				return *i;
			}
			self_type operator++ (int n) {

				content++;
				return *this;
			} 
			T& operator* () {

				return *content;
			}
			pointer operator-> (){

				return content;
			}
			bool operator== (const self_type& rhs) {

				return content == rhs.content;
			}
			bool operator!= (const self_type& rhs) {

				return content != rhs.content;
			}
			T& operator= (T& other) {

				content = *other;
				return other;
			}
			T* content;
		};

	template <class T, size_t N> 
		struct array {

			typedef T value_type;
			typedef size_t size_type;
			typedef ptrdiff_t difference_type;
			typedef value_type& reference;
			typedef const value_type& const_reference;
			typedef T* pointer;
			typedef const T* const_pointer;
			typedef array_iterator<T, N> iterator;
			typedef const array_iterator<T, N> const_iterator;
			typedef kstd::reverse_iterator <const_iterator> reverse_iterator;
			typedef kstd::reverse_iterator <const_iterator> const_reverse_iterator;
			reference operator [] (int index) {

				if (index > highestIndex) {

					highestIndex = index;
				}
				return content [index];
			}
			reference at (int index) {

				if (index >= N) [[unlikely]]  {

					//for now, be happy with returning nothing
					//later on, we will throw the correct error
				} else [[likely]] {
					return content [index];
				}
			}
			reference front () {

				return content [0];
			}
			reference back () {

				return content [N];
			}
			pointer data () {

				return content;
			}
			iterator cbegin () {

				return begin();
			}
			iterator cend () {

				return end();
			}
			iterator begin () {

				return iterator (*this, 0);
			} 

			iterator end () {

				return iterator (*this, N);
			}
			iterator crbegin () {

				return rbegin();
			}
			iterator crend () {

				return rend();
			}
			iterator rbegin () {

				return reverse_iterator (this, N);
			}
			iterator rend () {

				return reverse_iterator (this, 0);
			}
			bool empty () {

				if (size() != 0) [[likely]] {

					return false;
				} else [[unlikely]] {
					return true;
				}
			}
			size_t size () {

				return highestIndex;
			}
			size_t max_size () {

				return N;
			}
			void fill (T& input) {

				content[contSize];
			}
			void swap (array <T, N>& other) {
				//not sure how to implement






			}
			size_t highestIndex;
			size_t contSize;
			value_type content[N];
		};
	template <class T, size_t N>
		bool operator== (const array<T, N>& lhs, const array<T, N>& rhs) {


			for (int i = 0; i < N; i++) {

				if (lhs[i] != rhs[i]) {

					return true;
				}
			}
			return true;
		}
	template <class T, size_t N>
		bool operator!= (const array<T, N>& lhs, const array<T, N>& rhs) {


			return !(lhs == rhs);
		}
	template <class T, size_t N>
		bool operator< (const array<T, N>& lhs, const array<T, N>& rhs) {


			for (int i = 0; i < N; i++) {

				if (lhs[i] != rhs[i]) {

					return lhs[i] < rhs [i];
				}
			}
			return false;
		}
	template <class T, size_t N>
		bool operator<= (const array<T, N>& lhs, const array<T, N>& rhs) {


			for (int i = 0; i < N; i++) {

				if (lhs[i] != rhs[i]) {

					return lhs[i] <= rhs [i];
				}
			}
			return false;
		}
	template <class T, size_t N>
		bool operator> (const array<T, N>& lhs, const array<T, N>& rhs) {


			return !(lhs < rhs);
		}
	template <class T, size_t N>
		bool operator>= (const array<T, N>& lhs, const array<T, N>& rhs) {


			return !(lhs <= rhs);
		}
	template <size_t I, class T, size_t N>
		T& get (array<T, N>& other) {

			return other[I];
		}
	template <size_t I, class T, size_t N>
		T&& get (array<T, N>& other) {

			return other[I];
		}
	template <size_t I, class T, size_t N>
		const T& get (const array<T, N>& other) {

			return other[I];
		}
	template <size_t I, class T, size_t N>
		const T&& get (const array<T, N>& other) {

			return other[I];
		}

}



|
>
|
|

|
|
>
|
|
|
|
|
|
|
>
|
|
|
|
>
|
|
|
|
|
>
|
|
|
|
>
|
|
|
>
|
|
|
>
|
|
|
>
|
|
|
>
|
|
|
|
|

|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
>
|
>
|
|
|
|
|
>
|
>
|
|
|
|
|
|
|
>
|
|
|
>
|
|
|
>
|
|
|
>
|
|
|
>
|
|
|
>
|
|

|
>
|
|
|
>
|
|
|
>
|
|
|
>
|
|
|
>
|
|
|
>
|
>
|
|
|
|
|
|
>
|
|
|
>
|
|
|
>
|
|
<
<
>
>
>
>
>
>
|
|
|
|
|
|
<
>
>
|
>
|
>
|
|
|
|
|
|
<
>
>
|
|
|
<
>
>
|
>
|
>
|
|
|
|
|
|
<
>
>
|
>
|
>
|
|
|
|
|
|
<
>
>
|
|
|
<
>
>
|
|
|
|
>
|
|
|
|
>
|
|
|
|
>
|
|
|
|
>
|
|

<
>
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155


156
157
158
159
160
161
162
163
164
165
166
167

168
169
170
171
172
173
174
175
176
177
178
179

180
181
182
183
184

185
186
187
188
189
190
191
192
193
194
195
196

197
198
199
200
201
202
203
204
205
206
207
208

209
210
211
212
213

214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238

239
#pragma once
#include "iterator.hpp"

namespace kstd
{
template <class T, size_t N>
struct array;

template <class T, size_t N>
struct array_iterator
{
	typedef array_iterator self_type;
	typedef array<T, N> value_type;
	typedef array<T, N> &reference;
	typedef array<T, N> *pointer;
	typedef forward_iterator_tag iterator_category;
	typedef size_t difference_type;
	array_iterator(array<T, N> &other, size_t position)
	{
		content = other.content;
		content += position;
	}
	self_type operator++()
	{
		self_type *i = this;
		content++;
		return *i;
	}
	self_type operator++(int n)
	{
		content++;
		return *this;
	}
	T &operator*()
	{
		return *content;
	}
	pointer operator->()
	{
		return content;
	}
	bool operator==(const self_type &rhs)
	{
		return content == rhs.content;
	}
	bool operator!=(const self_type &rhs)
	{
		return content != rhs.content;
	}
	T &operator=(T &other)
	{
		content = *other;
		return other;
	}
	T *content;
};

template <class T, size_t N>
struct array
{
	typedef T value_type;
	typedef size_t size_type;
	typedef ptrdiff_t difference_type;
	typedef value_type &reference;
	typedef const value_type &const_reference;
	typedef T *pointer;
	typedef const T *const_pointer;
	typedef array_iterator<T, N> iterator;
	typedef const array_iterator<T, N> const_iterator;
	typedef kstd::reverse_iterator<const_iterator> reverse_iterator;
	typedef kstd::reverse_iterator<const_iterator> const_reverse_iterator;
	reference operator[](int index)
	{
		if (index > highestIndex)
		{
			highestIndex = index;
		}
		return content[index];
	}
	reference at(int index)
	{
		if (index >= N)
			[[unlikely]] {
				//for now, be happy with returning nothing
				//later on, we will throw the correct error
			} else [[likely]] {
				return content[index];
			}
	}
	reference front()
	{
		return content[0];
	}
	reference back()
	{
		return content[N];
	}
	pointer data()
	{
		return content;
	}
	iterator cbegin()
	{
		return begin();
	}
	iterator cend()
	{
		return end();
	}
	iterator begin()
	{
		return iterator(*this, 0);
	}

	iterator end()
	{
		return iterator(*this, N);
	}
	iterator crbegin()
	{
		return rbegin();
	}
	iterator crend()
	{
		return rend();
	}
	iterator rbegin()
	{
		return reverse_iterator(this, N);
	}
	iterator rend()
	{
		return reverse_iterator(this, 0);
	}
	bool empty()
	{
		if (size() != 0)
			[[likely]] {
				return false;
			} else [[unlikely]] {
				return true;
			}
	}
	size_t size()
	{
		return highestIndex;
	}
	size_t max_size()
	{
		return N;
	}
	void fill(T &input)
	{
		content[contSize];
	}


	void swap(array<T, N> &other)
	{
		char buffer[N];
		memcpy(buffer, &content, N);
		memcpy(&content, &other.content, N);
		memcpy(&content, buffer, N);
	}
	size_t highestIndex;
	size_t contSize;
	value_type content[N];
};
template <class T, size_t N>

bool operator==(const array<T, N> &lhs, const array<T, N> &rhs)
{
	for (int i = 0; i < N; i++)
	{
		if (lhs[i] != rhs[i])
		{
			return true;
		}
	}
	return true;
}
template <class T, size_t N>

bool operator!=(const array<T, N> &lhs, const array<T, N> &rhs)
{
	return !(lhs == rhs);
}
template <class T, size_t N>

bool operator<(const array<T, N> &lhs, const array<T, N> &rhs)
{
	for (int i = 0; i < N; i++)
	{
		if (lhs[i] != rhs[i])
		{
			return lhs[i] < rhs[i];
		}
	}
	return false;
}
template <class T, size_t N>

bool operator<=(const array<T, N> &lhs, const array<T, N> &rhs)
{
	for (int i = 0; i < N; i++)
	{
		if (lhs[i] != rhs[i])
		{
			return lhs[i] <= rhs[i];
		}
	}
	return false;
}
template <class T, size_t N>

bool operator>(const array<T, N> &lhs, const array<T, N> &rhs)
{
	return !(lhs < rhs);
}
template <class T, size_t N>

bool operator>=(const array<T, N> &lhs, const array<T, N> &rhs)
{
	return !(lhs <= rhs);
}
template <size_t I, class T, size_t N>
T &get(array<T, N> &other)
{
	return other[I];
}
template <size_t I, class T, size_t N>
T &&get(array<T, N> &other)
{
	return other[I];
}
template <size_t I, class T, size_t N>
const T &get(const array<T, N> &other)
{
	return other[I];
}
template <size_t I, class T, size_t N>
const T &&get(const array<T, N> &other)
{
	return other[I];
}


} // namespace kstd

Deleted include/kstd/ext/conscell.hpp.

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
#pragma once

namespace kstd {
	namespace ext {
		template <class T>
			class conscell {
			public: 
				typedef T member_type;
				typedef T* pointer_type;
				typedef T& reference_type;
				typedef conscell<T> self_type;
				typedef conscell<T>* self_pointer;
				typedef conscell<T>& self_reference;
				conscell () {

				}
				conscell (member_type other) {
					held = other;
				}
				conscell (self_reference other) {
					held = other.held;
					next = new conscell (other.next);
				}
				template <class U>
					conscell (conscell<U>& other) {

					}
				~conscell () {
					delete next;
				}
				void push_back (member_type other) {
					if (held == NULL) [[unlikely]] {
						held = other;
					} else  [[likely]] {
						if (next == nullptr) {
							next = new conscell <T>(other);
		
						} else {
							next->push_back (other);
						}
					}
				}
				reference_type operator[] (int index) {
					if (index == 0) [[unlikely]] {
						return held;
					} else [[likely]] {
						return (*next)[index-1];
					}
				}
				void prepend (reference_type other, size_t index) {
					if (index == 1) [[unlikely]] {
						conscell<T> *a = new conscell<T>(next);
						a.held = next;
						next = *a;
					} else [[likely]] {
						next->prepend (other, index-1);
					}
				}
			private:
				member_type held = NULL;
				self_pointer next = nullptr;
			};
	}
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































Deleted include/kstd/ext/numbers.hpp.

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
#pragma once

namespace kstd {
	namespace ext {
		const float NUMBER_PI = 3.1415926535; //source : https://www.angio.net/pi/digits/pi1000000.txt
		const float NUMBER_E  = 2.7182818284; //source : http://www-history.mcs.st-and.ac.uk/HistTopics/e_10000.html

		template<class Func>
			float integrate (float start, float end, float presicion, Func fx) {
				double value;
				for (; start <= end; start++)
					value += fx (start) * presicion;
				return value; 
			}
		template<class Func>
			float slope (float start, float end, Func fx) {
				return (fx (end) - fx (start));
			}
		template<class Cont>
			typename Cont::reference sum_container (Cont cont) {
				typename Cont::reference ret;
				for (auto i : cont) 
					ret += i;
				return ret;
			}
		template<class Cont>
			typename Cont::reference avg_container (Cont cont) {
				return sum_cont (cont) / cont.size();
			}
		//next tree functions require a sorted container
		template<class Cont>
			typename Cont::reference median_container (Cont cont) {
				return cont [cont.size() / 2];
			}
		template<class Cont>
			typename Cont::reference upper_quartile_container (Cont cont) {
				return cont [cont.size() * 0.75];
			}
		template<class Cont>
			typename Cont::reference lower_quatile_container (Cont cont) {
				return cont [cont.size() * 0.25];
			}
		template<class U, U a, U b>
			constexpr U add () {
				return a + b;
			}
		template<class U, U a, U b>
			constexpr U mult () {
				return a * b;
			}
		template<class U, U a, U b>
			constexpr U div () {
				return a / b;
			}
		template<class U, U a, U b>
			constexpr U sub () {
				return a + b;
			}
	}
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































Added include/kstd/ext/rangeit.hpp.


















































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#pragma once
#include "kstd/iterator.hpp"

namespace kstd
{
namespace ext
{
namespace NUMIT
{

template <class T>
class iterator
{
  public:
    typedef iterator<T> self_type;
    typedef const T value_type;
    typedef int difference_type;

    iterator(T pos, int inc)
    {
        position = pos;
        increment = inc;
    }
    value_type operator++()
    {
        T i = position;
        position += increment;
        return i;
    }
    value_type operator++(int utter_garbage)
    {
        position += increment;
        return position;
    }
    value_type operator*()
    {
        return position;
    }
    bool operator==(const self_type &rhs)
    {
        if (rhs.position == position)
        {
            return true;
        }
        return false;
    }
    bool operator!=(const self_type &rhs)
    {
        if (rhs.position == position)
        {
            return false;
        }
        return true;
    }
    T position;
    int increment;
};
} // namespace NUMIT

template <class T>
class range_iterator
{
  public:
    typedef NUMIT::iterator<T> iterator_type;

    range_iterator(T _start, T _end, T _increment = 0)
    {
        range_start = _start;
        range_end = _end;
        increment = _increment;
    }

    iterator_type begin()
    {
        return iterator_type(range_start, increment);
    }
    iterator_type end()
    {
        return iterator_type(range_end, increment);
    }

  private:
    T range_start;
    T range_end;
    T increment;
};

} // namespace ext
} // namespace kstd

Changes to include/kstd/iterator.hpp.

64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
	typedef typename iterator_traits<RanIt>::reference Ref;

  public:
	typedef RanIt iterator_type;
	reverse_iterator()
	{
	}
	explicit reverse_iterator(RanIt x)
	{
		current = x;
	}
	template <class U>
	reverse_iterator(const reverse_iterator<U> &x)
	{
		current = x.current;
	}
	RanIt base() const
	{
		return current;
	}
	Ref operator*() const
	{






|

<


|

<







64
65
66
67
68
69
70
71
72

73
74
75
76

77
78
79
80
81
82
83
	typedef typename iterator_traits<RanIt>::reference Ref;

  public:
	typedef RanIt iterator_type;
	reverse_iterator()
	{
	}
	explicit reverse_iterator(RanIt x) : current(x)
	{

	}
	template <class U>
	reverse_iterator(const reverse_iterator<U> &x) : current(x.current)
	{

	}
	RanIt base() const
	{
		return current;
	}
	Ref operator*() const
	{

Changes to include/kstd/memory.hpp.

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
	template <class U>
	allocator &operator=(const allocator<U> &x)
	{
	}
	pointer allocate(size_type n)
	{
		pointer ret = (pointer)malloc(sizeof(T) * n);
		for (size_type i = 0; i < n; i++)
		{
			ret[0] = *new T;
		}
		return ret;
	}
	template <class U>
	pointer allocate(size_type n, const U *hint = 0)
	{
		pointer ret = (pointer)malloc(sizeof(T) * n);
		for (size_type i = 0; i < n; i++)
		{
			ret[0] = *new T;
		}
		return ret;
	}
	void deallocate(pointer p, size_type n)
	{
		for (int i = 0; i < n; i++)
		{
			delete p[i];
		}
	}
	void construct(pointer p, const T &val)
	{
		new ((void)*p) T(val);
	}
	void destroy(pointer p)






<
<
<
<






<
<
<
<






|







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
	template <class U>
	allocator &operator=(const allocator<U> &x)
	{
	}
	pointer allocate(size_type n)
	{
		pointer ret = (pointer)malloc(sizeof(T) * n);




		return ret;
	}
	template <class U>
	pointer allocate(size_type n, const U *hint = 0)
	{
		pointer ret = (pointer)malloc(sizeof(T) * n);




		return ret;
	}
	void deallocate(pointer p, size_type n)
	{
		for (int i = 0; i < n; i++)
		{
			delete &p[i];
		}
	}
	void construct(pointer p, const T &val)
	{
		new ((void)*p) T(val);
	}
	void destroy(pointer p)

Deleted include/kstd/stl_test.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#pragma once
#include "vector.hpp"
#include "memory.hpp"
#include "../testing/testing.h"
#include "utility.hpp"
#include "iterator.hpp"
#include "array.hpp"
#include "tuple.hpp"
#include "ext/conscell.hpp"
#include "algorithm.hpp"
#include "ext/numbers.hpp"
#include "unordered_set.hpp"
#include "functional.hpp"

using namespace Termutils;

template <bool perform>
void stl_test()
{
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































Changes to include/kstd/tuple.hpp.

3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
..
80
81
82
83
84
85
86
87
namespace kstd
{
template <class _T, class... T>
class tuple
{
  public:
	tuple(){

	};
	explicit tuple(const T &...)
	{
	}
	tuple(const tuple &other)
	{
	}
	template <class... T2>
................................................................................
}
template <int Idx, class... T>
typename tuple_element<Idx, tuple<T...>>::type &
get(const tuple<T...> &tpl)
{
}

} // namespace kstd






|
<
<







 







|
3
4
5
6
7
8
9
10


11
12
13
14
15
16
17
..
78
79
80
81
82
83
84
85
namespace kstd
{
template <class _T, class... T>
class tuple
{
  public:
	tuple(){};


	explicit tuple(const T &...)
	{
	}
	tuple(const tuple &other)
	{
	}
	template <class... T2>
................................................................................
}
template <int Idx, class... T>
typename tuple_element<Idx, tuple<T...>>::type &
get(const tuple<T...> &tpl)
{
}

} // namespace ks

Added include/kstd/type_traits.hpp.




















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
#pragma once
#include "stdint.h"
#include "stddef.h"

namespace kstd
{
template <class _T, _T _V>
struct integral_constant
{
    static const _T value = _V;
    typedef _T value_type;
    typedef integral_constant<_T, _V> type;
};

typedef integral_constant<bool, true> true_type;
typedef integral_constant<bool, false> false_type;

template <class T, class U>
struct is_same : false_type
{
};

template <class T>
struct is_same<T, T> : true_type
{
};

template <class T>
struct remove_const
{
    typedef T type;
};
template <class T>
struct remove_const<const T>
{
    typedef T type;
};

template <class T>
struct remove_volatile
{
    typedef T type;
};
template <class T>
struct remove_volatile<volatile T>
{
    typedef T type;
};

template <class T>
struct remove_cv
{
    typedef typename remove_volatile<typename remove_const<T>::type>::type type;
};

template <class T>
struct add_const
{
    typedef const T type;
};

template <class T>
struct add_volatile
{
    typedef volatile T type;
};

template <class T>
struct add_cv
{
    typedef const volatile T type;
};

template <class T>
struct remove_reference
{
    typedef T type;
};
template <class T>
struct remove_reference<T &>
{
    typedef T type;
};
template <class T>
struct remove_reference<T &&>
{
    typedef T type;
};

template <class T>
struct add_reference
{
    typedef T &type;
};

template <class T>
struct remove_pointer
{
    typedef T type;
};
template <class T>
struct remove_pointer<T *>
{
    typedef T type;
};
template <class T>
struct remove_pointer<T **>
{
    typedef T type;
};

template <class T>
struct add_pointer
{
    typedef T *type;
};

template <class T>
struct remove_extent
{
    typedef T type;
};
template <class T>
struct remove_extent<T[]>
{
    typedef T type;
};
template <class T, size_t N>
struct remove_extent<T[N]>
{
    typedef T type;
};

template <class T>
struct remove_all_extents
{
    typedef T type;
};
template <class T>
struct remove_all_extents<T[]> : remove_all_extents<T>
{
};
template <class T, size_t N>
struct remove_all_extents<T[N]> : remove_all_extents<T>
{
};

template <size_t len, size_t align>
struct aligned_storage
{
    struct type
    {
        alignas(align) unsigned char data[len];
    };
};

template <class T>
struct is_void : is_same<typename remove_cv<T>::type, void>
{
};

template <class T>
struct is_integral_base : false_type
{
};
template <>
struct is_integral_base<bool> : true_type
{
};
template <>
struct is_integral_base<char> : true_type
{
};
template <>
struct is_integral_base<signed char> : true_type
{
};
template <>
struct is_integral_base<unsigned char> : true_type
{
};
template <>
struct is_integral_base<wchar_t> : true_type
{
};
template <>
struct is_integral_base<short> : true_type
{
};
template <>
struct is_integral_base<int> : true_type
{
};
template <>
struct is_integral_base<long> : true_type
{
};
template <>
struct is_integral_base<long long> : true_type
{
};
template <>
struct is_integral_base<unsigned short> : true_type
{
};
template <>
struct is_integral_base<unsigned int> : true_type
{
};
template <>
struct is_integral_base<unsigned long> : true_type
{
};
template <>
struct is_integral_base<unsigned long long> : true_type
{
};

template <class T>
struct is_integral : is_integral_base<typename remove_cv<T>::type>
{
};

template <class T>
struct is_floating_point_base : false_type
{
};
template <>
struct is_floating_point_base<float> : true_type
{
};
template <>
struct is_floating_point_base<double> : true_type
{
};
template <>
struct is_floating_point_base<long double> : true_type
{
};

template <class T>
struct is_floating_point : is_floating_point_base<typename remove_cv<T>::type>
{
};

template <class T>
struct is_reference : false_type
{
};

template <class T>
struct is_reference<T &> : true_type
{
};

template <class T>
struct is_array : false_type
{
};
template <class T>
struct is_array<T[]> : true_type
{
};
template <class T, size_t N>
struct is_array<T[N]> : true_type
{
};

template <class T>
struct is_pointer : false_type
{
};
template <class T>
struct is_pointer<T *> : true_type
{
};

template <class T>
struct is_arithmetic : integral_constant<bool, is_integral<T>::value || is_floating_point<T>::value>
{
};

template <class T>
struct is_fundamental : integral_constant<bool, is_arithmetic<T>::value || is_void<T>::value>
{
};

template <class T>
struct is_const : false_type
{
};
template <class T>
struct is_const<const T> : true_type
{
};

// primary template
template <class>
struct is_function : false_type
{
};

template <class Ret, class... Args>
struct is_function<Ret(Args...)> : true_type
{
};

template <class Ret, class... Args>
struct is_function<Ret(Args......)> : true_type
{
};

template <class Ret, class... Args>
struct is_function<Ret(Args...) const> : true_type
{
};
template <class Ret, class... Args>
struct is_function<Ret(Args...) volatile> : true_type
{
};
template <class Ret, class... Args>
struct is_function<Ret(Args...) const volatile> : true_type
{
};
template <class Ret, class... Args>
struct is_function<Ret(Args......) const> : true_type
{
};
template <class Ret, class... Args>
struct is_function<Ret(Args......) volatile> : true_type
{
};
template <class Ret, class... Args>
struct is_function<Ret(Args......) const volatile> : true_type
{
};
template <class Ret, class... Args>
struct is_function<Ret(Args...) &> : true_type
{
};
template <class Ret, class... Args>
struct is_function<Ret(Args...) const &> : true_type
{
};
template <class Ret, class... Args>
struct is_function<Ret(Args...) volatile &> : true_type
{
};
template <class Ret, class... Args>
struct is_function<Ret(Args...) const volatile &> : true_type
{
};
template <class Ret, class... Args>
struct is_function<Ret(Args......) &> : true_type
{
};
template <class Ret, class... Args>
struct is_function<Ret(Args......) const &> : true_type
{
};
template <class Ret, class... Args>
struct is_function<Ret(Args......) volatile &> : true_type
{
};
template <class Ret, class... Args>
struct is_function<Ret(Args......) const volatile &> : true_type
{
};
template <class Ret, class... Args>
struct is_function<Ret(Args...) &&> : true_type
{
};
template <class Ret, class... Args>
struct is_function<Ret(Args...) const &&> : true_type
{
};
template <class Ret, class... Args>
struct is_function<Ret(Args...) volatile &&> : true_type
{
};
template <class Ret, class... Args>
struct is_function<Ret(Args...) const volatile &&> : true_type
{
};
template <class Ret, class... Args>
struct is_function<Ret(Args......) &&> : true_type
{
};
template <class Ret, class... Args>
struct is_function<Ret(Args......) const &&> : true_type
{
};
template <class Ret, class... Args>
struct is_function<Ret(Args......) volatile &&> : true_type
{
};
template <class Ret, class... Args>
struct is_function<Ret(Args......) const volatile &&> : true_type
{
};

template <class Ret, class... Args>
struct is_function<Ret(Args...) noexcept> : true_type
{
};
template <class Ret, class... Args>
struct is_function<Ret(Args......) noexcept> : true_type
{
};
template <class Ret, class... Args>
struct is_function<Ret(Args...) const noexcept> : true_type
{
};
template <class Ret, class... Args>
struct is_function<Ret(Args...) volatile noexcept> : true_type
{
};
template <class Ret, class... Args>
struct is_function<Ret(Args...) const volatile noexcept> : true_type
{
};
template <class Ret, class... Args>
struct is_function<Ret(Args......) const noexcept> : true_type
{
};
template <class Ret, class... Args>
struct is_function<Ret(Args......) volatile noexcept> : true_type
{
};
template <class Ret, class... Args>
struct is_function<Ret(Args......) const volatile noexcept> : true_type
{
};
template <class Ret, class... Args>
struct is_function<Ret(Args...) & noexcept> : true_type
{
};
template <class Ret, class... Args>
struct is_function<Ret(Args...) const &noexcept> : true_type
{
};
template <class Ret, class... Args>
struct is_function<Ret(Args...) volatile &noexcept> : true_type
{
};
template <class Ret, class... Args>
struct is_function<Ret(Args...) const volatile &noexcept> : true_type
{
};
template <class Ret, class... Args>
struct is_function<Ret(Args......) & noexcept> : true_type
{
};
template <class Ret, class... Args>
struct is_function<Ret(Args......) const &noexcept> : true_type
{
};
template <class Ret, class... Args>
struct is_function<Ret(Args......) volatile &noexcept> : true_type
{
};
template <class Ret, class... Args>
struct is_function<Ret(Args......) const volatile &noexcept> : true_type
{
};
template <class Ret, class... Args>
struct is_function<Ret(Args...) && noexcept> : true_type
{
};
template <class Ret, class... Args>
struct is_function<Ret(Args...) const &&noexcept> : true_type
{
};
template <class Ret, class... Args>
struct is_function<Ret(Args...) volatile &&noexcept> : true_type
{
};
template <class Ret, class... Args>
struct is_function<Ret(Args...) const volatile &&noexcept> : true_type
{
};
template <class Ret, class... Args>
struct is_function<Ret(Args......) && noexcept> : true_type
{
};
template <class Ret, class... Args>
struct is_function<Ret(Args......) const &&noexcept> : true_type
{
};
template <class Ret, class... Args>
struct is_function<Ret(Args......) volatile &&noexcept> : true_type
{
};
template <class Ret, class... Args>
struct is_function<Ret(Args......) const volatile &&noexcept> : true_type
{
};

template <class T>
struct is_object : integral_constant<bool, !(is_reference<T>::value || is_void<T>::value || is_function<T>::value)>
{
};

template <class T>
struct is_union : integral_constant<bool, __is_union(T)>
{
};

template <class T>
struct is_class : integral_constant<bool, __is_class(T)>
{
};

template <class T>
struct is_enum : integral_constant<bool, __is_enum(T)>
{
};

template <class T>
struct is_member_function_pointer_helper : false_type
{
};

template <class T, class U>
struct is_member_function_pointer_helper<T U::*> : is_function<T>
{
};

template <class T>
struct is_member_function_pointer : is_member_function_pointer_helper<remove_cv<T>>
{
};

template <typename>
struct is_member_object_pointer_base
    : false_type
{
};

template <typename _Tp, typename _Cp>
struct is_member_object_pointer_base<_Tp _Cp::*>
    : integral_constant<bool, !is_function<_Tp>::value>
{
};

template <typename T>
struct is_member_object_pointer : is_member_object_pointer_base<typename remove_cv<T>::type>::type
{
};

template <class T>
struct is_member_pointer : integral_constant<bool, is_member_function_pointer<T>::value ||
                                                       is_member_object_pointer<T>::value>
{
};

template <class T>
struct is_scalar : integral_constant<bool, is_arithmetic<T>::value ||
                                               is_enum<T>::value ||
                                               is_pointer<T>::value ||
                                               is_member_pointer<T>::value>
{
};

template <class T>
struct is_volatile : false_type
{
};

template <class T>
struct is_volatile<volatile T> : true_type
{
};

template <class T>
struct is_pod : integral_constant<bool, __is_pod(T)>
{
};

template <class T>
struct is_empty : integral_constant<bool, __is_empty(T)>
{
};

template <class T>
struct is_polymorphic : integral_constant<bool, __is_polymorphic(T)>
{
};

template <class T>
struct is_abstract : integral_constant<bool, __is_abstract(T)>
{
};

template <class T>
struct has_trivial_constructor : integral_constant<bool,
                                                   __has_trivial_constructor(T)>
{
};

template <class T>
struct has_trivial_copy : integral_constant<bool, __has_trivial_copy(T)>
{
};

template <class T>
struct has_trivial_assign : integral_constant<bool, __has_trivial_assign(T)>
{
};

template <class T>
struct has_trivial_destructor : integral_constant<bool, __has_trivial_destructor(T)>
{
};

template <class T>
struct has_nothrow_constructor : integral_constant<bool, __has_nothrow_constructor(T)>
{
};

template <class T>
struct has_nothrow_copy : integral_constant<bool, __has_nothrow_copy(T)>
{
};

template <class T>
struct has_nothrow_assign : integral_constant<bool, __has_nothrow_assign(T)>
{
};

template <class T>
struct has_virtual_destructor : integral_constant<bool, __has_virtual_destructor(T)>
{
};

template <class T>
struct is_signed_base : false_type
{
};
template <>
struct is_signed_base<signed char> : true_type
{
};
template <>
struct is_signed_base<short> : true_type
{
};
template <>
struct is_signed_base<int> : true_type
{
};
template <>
struct is_signed_base<long> : true_type
{
};
template <>
struct is_signed_base<long long> : true_type
{
};

template <class T>
struct is_signed : is_signed_base<typename remove_cv<T>::type>
{
};

template <class T>
struct is_unsigned_base : false_type
{
};
template <>
struct is_unsigned_base<unsigned char> : true_type
{
};
template <>
struct is_unsigned_base<unsigned short> : true_type
{
};
template <>
struct is_unsigned_base<unsigned int> : true_type
{
};
template <>
struct is_unsigned_base<unsigned long> : true_type
{
};
template <>
struct is_unsigned_base<unsigned long long> : true_type
{
};

template <class T>
struct is_unsigned : is_unsigned_base<typename remove_cv<T>::type>
{
};

template <class T>
struct alignment_of : integral_constant<size_t, alignof(T)>
{
};

template <class T>
struct rank : integral_constant<size_t, 0>
{
};

template <class T>
struct rank<T[]> : integral_constant<size_t, rank<T>::value + 1>
{
};

template <class T, size_t N>
struct rank<T[N]> : integral_constant<size_t, rank<T>::value + 1>
{
};

template <class T, unsigned N = 0>
struct extent : integral_constant<size_t, 0>
{
};

template <class T>
struct extent<T[], 0> : integral_constant<size_t, 0>
{
};

template <class T, unsigned N>
struct extent<T[], N> : extent<T, N - 1>
{
};

template <class T, size_t I>
struct extent<T[I], 0> : integral_constant<size_t, I>
{
};

template <class T, size_t I, unsigned N>
struct extent<T[I], N> : extent<T, N - 1>
{
};

template <typename _From, typename _To>
struct is_convertible_base
{
  private:
    typedef char one;
    typedef struct
    {
        char arr[2];
    } two;
    static one test(_To);
    static two test(...);
    static _From makeFrom();

  public:
    static const bool value = sizeof(test(makeFrom())) == 1;
};

template <class T, class U>
struct is_convertible : integral_constant<bool, is_convertible_base<T, U>::value>
{
};

template <class T, class U>
struct is_base_of : integral_constant<bool, __is_base_of(T, U)>
{
};

template <bool B, class T = void>
struct enable_if
{
};

template <class T>
struct enable_if<true, T>
{
    typedef T type;
};
} // namespace kstd

Changes to include/kstd/utility.hpp.

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
55
56
57
58
59
60
61
62
63
64
65
66


67

68
69
70
71
72
73
74
75
struct pair
{
	typedef _T1 first_type;
	typedef _T2 second_type;
	_T1 first;
	_T2 second;
	pair() : first(), second() {}
	pair(const _T1 &__a, const _T2 &__b) : first(__a), second(__b) {}
	template <class _U1, class _U2>
	pair(const pair<_U1, _U2> &__p) : first(__p.first), second(__p.second) {}
};

template <typename T, typename U>
pair<T, U> make_pair(T a, U b)
{
	pair<T, U> ret;
	ret.first = a;
................................................................................

template <class T, class U>
bool operator>=(const pair<T, U> &x, const pair<T, U> &y)
{
	return !(x < y);
}

namespace rel_ops
{
template <typename T>
bool operator!=(T &a, T &b)
{


	return !(a == b);

}
template <typename T>
bool operator<=(const T &x, const T &y)
{
	return !(y < x);
}
} // namespace rel_ops
} // namespace kstd






|

|







 







<
<
|
|

>
>
|
>

<
<
|
<
<
<

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
55
56
57
58
59
60
61


62
63
64
65
66
67
68
69


70



71
struct pair
{
	typedef _T1 first_type;
	typedef _T2 second_type;
	_T1 first;
	_T2 second;
	pair() : first(), second() {}
	pair(const _T1 &a, const _T2 &b) : first(a), second(b) {}
	template <class _U1, class _U2>
	pair(const pair<_U1, _U2> &p) : first(p.first), second(p.second) {}
};

template <typename T, typename U>
pair<T, U> make_pair(T a, U b)
{
	pair<T, U> ret;
	ret.first = a;
................................................................................

template <class T, class U>
bool operator>=(const pair<T, U> &x, const pair<T, U> &y)
{
	return !(x < y);
}



template <class T>
void swap(T &a, T &b)
{
	char buffer[sizeof(T)];
	memcpy(buffer, &a, sizeof(T));
	memcpy(&a, &b, sizeof(T));
	memcpy(&b, buffer, sizeof(T));
}






} // namespace kstd

Changes to include/kstd/vector.hpp.

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
76
77
78
79










80
81
82
83
84
85
86
87
88
89
90
91
92










93

94








95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164

165
166
167

168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240

241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
...
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
...
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471

472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
#pragma once
#include "memory.hpp"

#include "libk/string.h"



namespace kstd
{
template <class T, class A = allocator<T>>
class vector;

namespace __VEC_IT
{ //iterators for kstd::vector

template <class T>
class iterator
{
  public:
	typedef kstd::__VEC_IT::iterator<T> self_type;
	typedef T value_type;
	typedef T &reference;
	typedef T *pointer;
	typedef kstd::forward_iterator_tag iterator_category;
	typedef int difference_type;

	iterator(kstd::vector<value_type> &other, size_t pos)










	{
		ptr_ = other;
		position = pos;
	}
	self_type operator++()
	{
		self_type i = ptr_[position];
		position++;
		return i;
	}
	self_type operator++(int pf)
	{
		position++;










		return ptr_[position];









	}
	reference operator*()
	{
		return ptr_[position];
	}
	pointer operator->()
	{
		return &ptr_[position];
	}
	bool operator==(const self_type &rhs)
	{
		if (rhs.position == position && rhs.ptr_ == ptr_)
		{
			return true;
		}
		return false;
	}
	bool operator!=(const self_type &rhs)
	{
		if (rhs.position == position && rhs.ptr_ == ptr_)
		{
			return false;
		}
		return true;
	}
	size_t position;
	kstd::vector<value_type> &ptr_;
};

template <class T>
class const_iterator
{
  public:
	typedef iterator<T> self_type;
	typedef T value_type;
	typedef T &reference;
	typedef T *pointer;
	typedef kstd::forward_iterator_tag iterator_category;
	typedef int difference_type;

	const_iterator(kstd::vector<value_type> &other, size_t pos)










	{
		ptr_ = other;
		position = pos;
	}
	self_type operator++()
	{
		self_type i = ptr_[position];
		position++;
		return i;
	}
	self_type operator++(int pf)
	{
		position++;










		return ptr_[position];

	}








	const reference operator*()
	{
		return ptr_[position];
	}
	const pointer operator->()
	{
		return &ptr_[position];
	}
	bool operator==(const self_type &rhs)
	{
		if (rhs.position == position && rhs.ptr_ == ptr_)
		{
			return true;
		}
		return false;
	}
	bool operator!=(const self_type &rhs)
	{
		if (rhs.position == position && rhs.ptr_ == ptr_)
		{
			return false;
		}
		return true;
	}
	size_t position;
	kstd::vector<value_type> &ptr_;
};
} // namespace __VEC_IT

template <class T, class A>
bool operator==(const vector<T, A> &lhs, const vector<T, A> &rhs)
{
	return (lhs.size() == rhs.size() && equal(lhs.begin(), lhs.end(), rhs.begin()));
}

template <class T, class A>
bool operator!=(const vector<T, A> &lhs, const vector<T, A> &rhs)
{
	return !(lhs == rhs);
}

template <class T, class A>
bool operator<(const vector<T, A> &lhs, const vector<T, A> &rhs)
{
	return lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
}

template <class T, class A>
bool operator<=(const vector<T, A> &lhs, const vector<T, A> &rhs)
{
	return !(rhs < lhs);
}

template <class T, class A>
bool operator>(const vector<T, A> &lhs, const vector<T, A> &rhs)
{
	return rhs < lhs;
}

template <class T, class A>
bool operator>=(const vector<T, A> &lhs, const vector<T, A> &rhs)
{
	return !(lhs < rhs);
}

template <class T, class A>
void swap(vector<T, A> &lhs, vector<T, A> &rhs)
{
	lhs.swap(rhs);
}

template <class T, class A>
class vector
{

	typedef A allocator_type;
	typedef typename A::pointer pointer;
	typedef typename A::const_pointer const_pointer;
	typedef typename A::reference reference;
	typedef typename A::const_reference const_reference;
	typedef typename A::value_type value_type;
	typedef __VEC_IT::iterator<T> iterator;
	typedef __VEC_IT::const_iterator<T> const_iterator;
	typedef size_t size_type;
	typedef int difference_type;
	typedef kstd::reverse_iterator<const_iterator> const_reverse_iterator;
	typedef kstd::reverse_iterator<iterator> reverse_iterator;

	vector()
	{
		prealloc_size = 5;
		data = alloc.allocate(prealloc_size * sizeof(T));
	}

	explicit vector(const A &a1)
	{
		alloc = a1;
		prealloc_size = 5;
		data = alloc.allocate(prealloc_size * sizeof(T));
	}

	explicit vector(size_type n)
	{
		data = alloc.allocate(n * sizeof(T));
	}

	vector(size_type n, const T &x)
	{
		prealloc_size = 5;
		for (size_type i = 0; i < n; i++)
		{
			push_back(x);
		}
	}

	vector(size_type n, const T &x, const A &a1)
	{
		alloc = a1;
		prealloc_size = 5;
		for (size_type i = 0; i < n; i++)
		{
			push_back(x);
		}
	}

	vector(const vector &x)
	{
		prealloc_size = 5;
		for (auto i : x)
		{
			push_back(i);
		}
	}

	template <class InIt>
	vector(InIt first, InIt last)
	{
		prealloc_size = 5;
		while (first++ != last)
		{
			push_back(*first);
		}
	}

	template <class InIt>
	vector(InIt first, InIt last, const A &a1)
	{
		alloc = a1;

		prealloc_size = 5;
		while (first++ != last)
		{
			push_back(*first);
		}
	}

	~vector()
	{
		alloc.deallocate(data);
	}

	void reserve(size_type n)
	{
		preallocate(prealloc_size - n);
	}

	size_type capacity() const
	{
		return prealloc_size;
	}

	iterator begin()
	{
		return iterator(*this, 0);
	}

	const_iterator begin() const
	{
		return const_iterator(*this, 0);
	}

	iterator end()
	{
		return iterator(*this, vec_size);
	}

	const_iterator end() const
	{
		return iterator(*this, vec_size);
	}

	reverse_iterator rbegin()
	{
		return reverse_iterator(*this, vec_size);
	}

	const_reverse_iterator rbegin() const
	{
		return reverse_iterator(*this, vec_size);
	}

	reverse_iterator rend()
	{
		return reverse_iterator(*this, 0);
	}

	const_reverse_iterator rend() const
	{
		return reverse_iterator(*this, 0);
	}

	void resize(size_type n)
	{
		vec_size = n;
	}

	void resize(size_type n, T x)
	{
		vec_size = 0;
		for (size_type i = 0; i < n; i++)
		{
			push_back(x);
		}
	}

	size_type size() const
	{
		return vec_size;
	}

................................................................................
	size_type max_size() const
	{
		return vec_size;
	}

	bool empty() const
	{
		if (vec_size == 0)
		{
			return true;
		}
		return false;
	}

	reference at(size_type pos)
	{
		if (pos < vec_size)
		{
			return data[pos];
		}
		else
		{
			return NULL;
			//ARRAY OUT OF BOUNDS!
		}
	}

	const_reference at(size_type pos) const
	{
		if (pos < vec_size)
		{
			return data[pos];
		}
		else
		{
			return NULL;
			//ARRAY OUT OF BOUNDS!
		}
	}

	reference operator[](size_type pos)
	{
		return data[pos];
	}

................................................................................
	const_reference front() const
	{
		return data[0];
	}

	reference back()
	{
		return data[vec_size];
	}

	const_reference back() const
	{
		return data[vec_size];
	}

	void push_back(const T &x)
	{
		if (vec_size == prealloc_size)
		{
			preallocate();
		}
		else
		{
			data[vec_size] = x;
			vec_size++;
		}
	}
	void pop_back()
	{
		vec_size--;
	}

	template <class InIt>
	void assign(InIt first, InIt last)
	{
		resize(0);
		while (first != last)
		{
			push_back(*first);
		}
	}

	void assign(size_type n, const T &x)
	{
		resize(n);
		for (int i = 0; i < n; i++)
		{
			data[i] = x;
		}
	}

	iterator insert(iterator it, const T &x)
	{
		iterator cpit = it;
		size_type cpsz;
		vector<T, A> cpvec;
		for (; cpit != end(); cpit++)
		{
			cpsz++;
			cpvec.push_back(*cpit);
		}
		for (size_type i = 0; i < cpsz; i++)
		{
			pop_back();
		}
		push_back(x);
		for (iterator i = cpvec.begin(); i != cpvec.end(); i++)
		{
			push_back(*i);
		}
	}

	void insert(iterator it, size_type n, const T &x)
	{
		for (size_type i = 0; i < n; i++, it++)
		{
			insert(it, x);
		}
	}

	template <class InIt>
	void insert(iterator it, InIt first, InIt last)
	{
		for (; first != last; first++, it++)
		{
			insert(it, *first);
		}
	}

	iterator erase(iterator it_)
	{
		for (int i = it_.position; i < vec_size - 1; i++)
		{
			data[i] = data[i + 1];
		}

	}

	iterator erase(iterator first, iterator last)
	{
		while (first++ != last)
		{
			erase(first);
		}
	}

	void clear()
	{
		vec_size = 0;
		erase(begin(), end());
	}

	A get_allocator() const
	{
		return alloc;
	}

	void swap(vector &x)
	{
		T tempdata = data;
		data = x.data;
		x.data = tempdata;
	}

  protected:
	void preallocate()
	{
		prealloc_size *= 1.5;
		T *tempbuff = alloc.allocate(prealloc_size * sizeof(T));
		memcpy(data, tempbuff, vec_size * sizeof(T));
		alloc.deallocate(data);
		data = tempbuff;
	}

	T *data;
	size_type vec_size;
	size_type prealloc_size;
	allocator_type alloc;
};

template <class A>
class vector<bool, A>
{
	typedef bool T;
	typedef A allocator_type;
	typedef typename A::pointer pointer;
	typedef typename A::const_pointer const_pointer;
	typedef typename A::value_type value_type;
	typedef __VEC_IT::iterator<T> iterator;
	typedef __VEC_IT::const_iterator<T> const_iterator;
	typedef size_t size_type;
	typedef int difference_type;
	typedef kstd::reverse_iterator<const_iterator> const_reverse_iterator;
	typedef kstd::reverse_iterator<iterator> reverse_iterator;
	class reference
	{
	  public:
		reference &operator=(const reference &x)
		{
			pt = x;
		}
		reference &operator=(bool x)
		{
			pt = x;
		}
		void flip()
		{
			pt != pt;
		}
		bool operator~() const
		{
			return !pt;
		}
		operator bool() const
		{
			return pt;
		}

	  private:
		bool &pt;
	};
	typedef bool const_reference;

	void flip()
	{
		for (size_type i = 0; i < vec_size; i++)
		{
			data[i] != data[i];
		}
	}

	static void swap(reference x, reference y)
	{
		bool tmp = bool(x);
		x = bool(y);
		y = tmp;
	}

	vector()
	{
		prealloc_size = 5;
		data = alloc.allocate(prealloc_size * sizeof(T));
	}

	explicit vector(const A &a1)
	{
		alloc = a1;
		prealloc_size = 5;
		data = alloc.allocate(prealloc_size * sizeof(T));
	}

	explicit vector(size_type n)
	{
		data = alloc.allocate(n * sizeof(T));
	}

	vector(size_type n, const T &x)
	{
		prealloc_size = 5;
		for (size_type i = 0; i < n; i++)
		{
			push_back(x);
		}
	}

	vector(size_type n, const T &x, const A &a1)
	{
		alloc = a1;
		prealloc_size = 5;
		for (size_type i = 0; i < n; i++)
		{
			push_back(x);
		}
	}

	vector(const vector &x)
	{
		prealloc_size = 5;
		for (auto i : x)
		{
			push_back(i);
		}
	}

	template <class InIt>
	vector(InIt first, InIt last)
	{
		prealloc_size = 5;
		while (first++ != last)
		{
			push_back(*first);
		}
	}

	template <class InIt>
	vector(InIt first, InIt last, const A &a1)
	{
		alloc = a1;
		prealloc_size = 5;
		while (first++ != last)
		{
			push_back(*first);
		}
	}

	~vector()
	{
		alloc.deallocate(data);
	}

	void reserve(size_type n)
	{
		preallocate(prealloc_size - n);
	}

	size_type capacity() const
	{
		return prealloc_size;
	}

	iterator begin()
	{
		return iterator(*this, 0);
	}

	const_iterator begin() const
	{
		return const_iterator(*this, 0);
	}

	iterator end()
	{
		return iterator(*this, vec_size);
	}

	const_iterator end() const
	{
		return const_iterator(*this, vec_size);
	}

	reverse_iterator rbegin()
	{
		return reverse_iterator(*this, vec_size);
	}

	const_reverse_iterator rbegin() const
	{
		return reverse_iterator(*this, vec_size);
	}

	reverse_iterator rend()
	{
		return reverse_iterator(*this, 0);
	}

	const_reverse_iterator rend() const
	{
		return reverse_iterator(*this, 0);
	}

	void resize(size_type n)
	{
		vec_size = n;
	}

	void resize(size_type n, T x)
	{
		vec_size = 0;
		for (size_type i = 0; i < n; i++)
		{
			push_back(x);
		}
	}

	size_type size() const
	{
		return vec_size;
	}

	size_type max_size() const
	{
		return vec_size;
	}

	bool empty() const
	{
		if (vec_size == 0)
		{
			return true;
		}
		return false;
	}

	reference at(size_type pos)
	{
		if (pos < vec_size)
		{
			return data[pos];
		}
		else
		{
			return NULL;
			//ARRAY OUT OF BOUNDS!
		}
	}

	const_reference at(size_type pos) const
	{
		if (pos < vec_size)
		{
			return data[pos];
		}
		else
		{
			return NULL;
			//ARRAY OUT OF BOUNDS!
		}
	}

	reference operator[](size_type pos)
	{
		return data[pos];
	}

	const_reference operator[](size_type pos) const
	{
		return data[pos];
	}

	reference front()
	{
		return data[0];
	}

	const_reference front() const
	{
		return data[0];
	}

	reference back()
	{
		return data[vec_size];
	}

	const_reference back() const
	{
		return data[vec_size];
	}

	void push_back(const T &x)
	{
		if (vec_size == prealloc_size)
		{
			preallocate();
		}
		else
		{
			data[vec_size] = x;
			vec_size++;
		}
	}
	void pop_back()
	{
		vec_size--;
	}

	template <class InIt>
	void assign(InIt first, InIt last)
	{
		resize(0);
		while (first != last)
		{
			push_back(*first);
		}
	}

	void assign(size_type n, const T &x)
	{
		resize(n);
		for (int i = 0; i < n; i++)
		{
			data[i] = x;
		}
	}

	iterator insert(iterator it, const T &x)
	{
		iterator cpit = it;
		size_type cpsz;
		vector<T, A> cpvec;
		for (; cpit != end(); cpit++)
		{
			cpsz++;
			cpvec.push_back(*cpit);
		}
		for (size_type i = 0; i < cpsz; i++)
		{
			pop_back();
		}
		push_back(x);
		for (iterator i = cpvec.begin(); i != cpvec.end(); i++)
		{
			push_back(*i);
		}
	}

	void insert(iterator it, size_type n, const T &x)
	{
		for (size_type i = 0; i < n; i++, it++)
		{
			insert(it, x);
		}
	}

	template <class InIt>
	void insert(iterator it, InIt first, InIt last)
	{
		for (; first != last; first++, it++)
		{
			insert(it, *first);
		}
	}

	iterator erase(iterator it_)
	{
		for (int i = it_.position; i < vec_size - 1; i++)
		{
			data[i] = data[i + 1];
		}
	}

	iterator erase(iterator first, iterator last)
	{
		while (first++ != last)
		{
			erase(first);
		}
	}

	void clear()
	{
		vec_size = 0;
		erase(begin(), end());
	}

	A get_allocator() const
	{
		return alloc;
	}

	void swap(vector &x)
	{
		T tempdata = data;
		data = x.data;
		x.data = tempdata;
	}

  protected:
	void preallocate()
	{
		prealloc_size *= 1.5;
		T *tempbuff = alloc.allocate(prealloc_size * sizeof(T));
		memcpy(data, tempbuff, vec_size * sizeof(T));
		alloc.deallocate(data);
		data = tempbuff;
	}

  private:
	T *data;
	size_type vec_size;
	size_type prealloc_size;
	allocator_type alloc;
};

} // namespace kstd

>

>
>






|



|


|






|
>
>
>
>
>
>
>
>
>
>




|

|
|


|


>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>











|
<
<
<
<



<
<
|
|
<
|

|






|

|




|
>
>
>
>
>
>
>
>
>
>




|

|
|


|


>
>
>
>
>
>
>
>
>
>
|
>

>
>
>
>
>
>
>
>
|



|





|
<
<
<
<



<
<
<
<
|


|

|







|





|





|





|





|





|




>



>






|
|


|




|
<


|

<
|
<




<
<
<
<
<
<
|
<
|
|
|
<
|

<
<
|
<

<



|
|
|
|
<
<



<
<
<
<
<
<
<
<
<
<
|

<
>


<

<




|




|









|




|




|




|




|




|




|




|




|




|
|
|
|
|







 







|
<
<
<
<





<

<

<


<





<

<

<


<







 







|




|





<

<
<
<
|
|
<











<
|
<






<

<













<

<


<

<





<

<






<

<




|
|
|
|
>





<

<





<









|







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|


<
<
<
<
<
<
<
|

<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


|



<





<

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
76
77
78
79
80
81
82




83
84
85


86
87

88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159




160
161
162




163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231

232
233
234
235

236

237
238
239
240






241

242
243
244

245
246


247

248

249
250
251
252
253
254
255


256
257
258










259
260

261
262
263

264

265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
...
341
342
343
344
345
346
347
348




349
350
351
352
353

354

355

356
357

358
359
360
361
362

363

364

365
366

367
368
369
370
371
372
373
...
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401

402



403
404

405
406
407
408
409
410
411
412
413
414
415

416

417
418
419
420
421
422

423

424
425
426
427
428
429
430
431
432
433
434
435
436

437

438
439

440

441
442
443
444
445

446

447
448
449
450
451
452

453

454
455
456
457
458
459
460
461
462
463
464
465
466
467

468

469
470
471
472
473

474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490










































































491
492
493







494
495





496









497




































































































































































































































































































498
499
500
501
502
503

504
505
506
507
508

509
#pragma once
#include "memory.hpp"
#include "algorithm.hpp"
#include "libk/string.h"
#include "termutils/terminal.h"
#include "type_traits.hpp"

namespace kstd
{
template <class T, class A = allocator<T>>
class vector;

namespace VEC_IT
{ //iterators for kstd::vector

template <class T>
class iterator : public kstd::iterator<kstd::forward_iterator_tag, T>
{
  public:
	typedef kstd::VEC_IT::iterator<T> self_type;
	typedef T value_type;
	typedef T &reference;
	typedef T *pointer;
	typedef kstd::forward_iterator_tag iterator_category;
	typedef int difference_type;

	iterator()
	{
	}

	iterator(self_type &other)
	{
		ptr_ = other.ptr_ - other.position;
		position = other.position;
	}

	iterator(value_type *other, size_t pos)
	{
		ptr_ = other;
		position = pos;
	}
	self_type operator++(int pf)
	{
		self_type i = self_type(ptr_, position);
		++(*this);
		return i;
	}
	self_type operator++()
	{
		position++;
		return self_type(ptr_, position);
	}
	self_type operator--(int pf)
	{
		self_type i = self_type(ptr_, position);
		--(*this);
		return i;
	}
	self_type operator--()
	{
		position--;
		return self_type(ptr_, position);
	}
	self_type operator-(const int &rhs) const
	{
		return self_type(ptr_ - position, position - rhs);
	}
	self_type operator+(const int rhs) const
	{
		return self_type(ptr_ - position, position + rhs);
	}
	reference operator*()
	{
		return ptr_[position];
	}
	pointer operator->()
	{
		return &ptr_[position];
	}
	bool operator==(const self_type &rhs)
	{
		return rhs.position == position && rhs.ptr_ == ptr_;




	}
	bool operator!=(const self_type &rhs)
	{


		return !(*this == rhs);
	}


	size_t position;
	value_type *ptr_;
};

template <class T>
class const_iterator
{
  public:
	typedef const_iterator<T> self_type;
	typedef T value_type;
	typedef const T &reference;
	typedef T *pointer;
	typedef kstd::forward_iterator_tag iterator_category;
	typedef int difference_type;

	const_iterator()
	{
	}

	const_iterator(self_type &other)
	{
		ptr_ = other.ptr_ - other.position;
		position = other.position;
	}

	const_iterator(value_type *other, size_t pos)
	{
		ptr_ = other;
		position = pos;
	}
	self_type operator++(int pf)
	{
		self_type i = self_type(ptr_, position);
		++(*this);
		return i;
	}
	self_type operator++()
	{
		position++;
		return self_type(ptr_, position);
	}
	self_type operator--(int pf)
	{
		self_type i = self_type(ptr_, position);
		--(*this);
		return i;
	}
	self_type operator--()
	{
		position--;
		return self_type(ptr_, position);
	}
	self_type operator-(const int rhs) const
	{
		return self_type(ptr_ - position, position - rhs);
	}
	self_type operator+(const int rhs) const
	{
		return self_type(ptr_ - position, position + rhs);
	}
	reference operator*() const
	{
		return ptr_[position];
	}
	pointer operator->() const
	{
		return &ptr_[position];
	}
	bool operator==(const self_type &rhs)
	{
		return rhs.position == position && rhs.ptr_ == ptr_;




	}
	bool operator!=(const self_type &rhs)
	{




		return !(*this == rhs);
	}
	size_t position;
	value_type *ptr_;
};
} // namespace VEC_IT

template <class T, class A>
bool operator==(const vector<T, A> &lhs, const vector<T, A> &rhs)
{
	return (lhs.size() == rhs.size() && equal(lhs.begin(), lhs.end(), rhs.begin()));
}

template <class T, class A = allocator<T>>
bool operator!=(const vector<T, A> &lhs, const vector<T, A> &rhs)
{
	return !(lhs == rhs);
}

template <class T, class A = allocator<T>>
bool operator<(const vector<T, A> &lhs, const vector<T, A> &rhs)
{
	return lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
}

template <class T, class A = allocator<T>>
bool operator<=(const vector<T, A> &lhs, const vector<T, A> &rhs)
{
	return !(rhs < lhs);
}

template <class T, class A = allocator<T>>
bool operator>(const vector<T, A> &lhs, const vector<T, A> &rhs)
{
	return rhs < lhs;
}

template <class T, class A = allocator<T>>
bool operator>=(const vector<T, A> &lhs, const vector<T, A> &rhs)
{
	return !(lhs < rhs);
}

template <class T, class A = allocator<T>>
void swap(vector<T, A> &lhs, vector<T, A> &rhs)
{
	lhs.swap(rhs);
}

template <class T, class A>
class vector
{
  public:
	typedef A allocator_type;
	typedef typename A::pointer pointer;
	typedef typename A::const_pointer const_pointer;
	typedef typename A::reference reference;
	typedef typename A::const_reference const_reference;
	typedef typename A::value_type value_type;
	typedef VEC_IT::iterator<T> iterator;
	typedef VEC_IT::const_iterator<T> const_iterator;
	typedef size_t size_type;
	typedef int difference_type;
	typedef const kstd::reverse_iterator<const_iterator> const_reverse_iterator;
	typedef kstd::reverse_iterator<iterator> reverse_iterator;

	vector()
	{
		preallocate(5);

	}

	explicit vector(const A &a) : alloc(a)
	{

		preallocate(5);

	}

	explicit vector(size_type n)
	{






		for (size_t i = 0; i < n; ++i)

			push_back(T{});
	}


	explicit vector(size_type n, const T &x, const A &a = kstd::allocator<T>{}) : alloc(a)
	{


		for (size_t i = 0; i < n; ++i)

			push_back(x);

	}

	vector(const vector &x)
		: vec_size(x.vec_size), prealloc_size(x.prealloc_size)
	{
		preallocate(prealloc_size);
		memcpy(data, x.data, vec_size);


	}

	template <class InIt>










	vector(InIt first, InIt last, const A &a = kstd::allocator<T>{}, typename enable_if<!is_same<InIt, int>::value>::type * = 0) : alloc(a)
	{

		using enable_if_t = typename enable_if<!is_same<InIt, int>::value, InIt>::type;
		prealloc_size = 5;
		while (first++ != last)

			push_back(*first);

	}

	~vector()
	{
		alloc.deallocate(data, prealloc_size);
	}

	void reserve(size_type n)
	{
		preallocate(prealloc_size + n);
	}

	size_type capacity() const
	{
		return prealloc_size;
	}

	iterator begin()
	{
		return iterator(data, 0);
	}

	const_iterator begin() const
	{
		return const_iterator(data, 0);
	}

	iterator end()
	{
		return iterator(data, vec_size);
	}

	const_iterator end() const
	{
		return const_iterator(data, vec_size);
	}

	reverse_iterator rbegin()
	{
		return reverse_iterator(iterator(data, vec_size));
	}

	const_reverse_iterator rbegin() const
	{
		return const_reverse_iterator(const_iterator(data, vec_size));
	}

	reverse_iterator rend()
	{
		return reverse_iterator(iterator(data, 0));
	}

	const_reverse_iterator rend() const
	{
		return const_reverse_iterator(const_iterator(data, 0));
	}

	void resize(size_type n)
	{
		resize(n, T());
	}

	void resize(size_type n, T x)
	{
		if (n >= vec_size)
			for (size_t i = vec_size; i < n; i++)
				push_back(x);
		else
			erase(begin() + n, end());
	}

	size_type size() const
	{
		return vec_size;
	}

................................................................................
	size_type max_size() const
	{
		return vec_size;
	}

	bool empty() const
	{
		return vec_size == 0;




	}

	reference at(size_type pos)
	{
		if (pos < vec_size)

			return data[pos];

		else

			return NULL;
			//ARRAY OUT OF BOUNDS!

	}

	const_reference at(size_type pos) const
	{
		if (pos < vec_size)

			return data[pos];

		else

			return NULL;
			//ARRAY OUT OF BOUNDS!

	}

	reference operator[](size_type pos)
	{
		return data[pos];
	}

................................................................................
	const_reference front() const
	{
		return data[0];
	}

	reference back()
	{
		return data[vec_size - 1];
	}

	const_reference back() const
	{
		return data[vec_size - 1];
	}

	void push_back(const T &x)
	{
		if (vec_size == prealloc_size)

			preallocate();



		data[vec_size] = x;
		vec_size++;

	}
	void pop_back()
	{
		vec_size--;
	}

	template <class InIt>
	void assign(InIt first, InIt last)
	{
		resize(0);
		while (first != last)

			push_back(*(first++));

	}

	void assign(size_type n, const T &x)
	{
		resize(n);
		for (int i = 0; i < n; i++)

			data[i] = x;

	}

	iterator insert(iterator it, const T &x)
	{
		iterator cpit = it;
		size_type cpsz;
		vector<T, A> cpvec;
		for (; cpit != end(); cpit++)
		{
			cpsz++;
			cpvec.push_back(*cpit);
		}
		for (size_type i = 0; i < cpsz; i++)

			pop_back();

		push_back(x);
		for (iterator i = cpvec.begin(); i != cpvec.end(); i++)

			push_back(*i);

	}

	void insert(iterator it, size_type n, const T &x)
	{
		for (size_type i = 0; i < n; i++, it++)

			insert(it, x);

	}

	template <class InIt>
	void insert(iterator it, InIt first, InIt last)
	{
		for (; first != last; first++, it++)

			insert(it, *first);

	}

	iterator erase(iterator it_)
	{
		size_t tmp_size = vec_size - 1;
		for (size_t i = it_.position; i < tmp_size; i++)
			data[i] = data[i + 1];
		vec_size = tmp_size;
		return begin() + it_.position;
	}

	iterator erase(iterator first, iterator last)
	{
		while (first++ != last)

			erase(first);

	}

	void clear()
	{
		vec_size = 0;

	}

	A get_allocator() const
	{
		return alloc;
	}

	void swap(vector &x)
	{
		T &tempdata = data;
		data = x.data;
		x.data = tempdata;
	}

  protected:
	void preallocate()
	{










































































		preallocate(prealloc_size  * 1.5);
	}








	void preallocate(size_type new_size)
	{





		int old_prealloc_size = new_size;









		prealloc_size = new_size;




































































































































































































































































































		T *tempbuff = alloc.allocate(prealloc_size * sizeof(T));
		memcpy(data, tempbuff, vec_size * sizeof(T));
		alloc.deallocate(data, old_prealloc_size);
		data = tempbuff;
	}


	T *data;
	size_type vec_size;
	size_type prealloc_size;
	allocator_type alloc;
};

} // namespace kstd

Changes to include/libk/string.h.

7
8
9
10
11
12
13
14
15
16
17
18
#endif

    int memcmp(const void *, const void *, size_t);
    void *memcpy(void *, const void *, size_t);
    void *memmove(void *, const void *, size_t);
    void *memset(void *, int, size_t);
    size_t strlen(const char *);
    bool strcompare(const char *, const char *);

#ifdef __cplusplus
}
#endif






<




7
8
9
10
11
12
13

14
15
16
17
#endif

    int memcmp(const void *, const void *, size_t);
    void *memcpy(void *, const void *, size_t);
    void *memmove(void *, const void *, size_t);
    void *memset(void *, int, size_t);
    size_t strlen(const char *);


#ifdef __cplusplus
}
#endif

Changes to include/memory/lma_allocator.h.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class lma_allocator
{
	void *allocate(size_t sz)
	{
		return allocate(sz);
	}
	void desallocate(void *ptr)
	{
		return desallocate(ptr);
	}
};
} // namespace LMA
} // namespace Physical
} // namespace Paging

const struct LMA_t
{
} USE_LMA;
void *operator new(size_t sz, LMA_t use_lma);
void operator delete(void *ptr, LMA_t use_lma);






|

|











12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class lma_allocator
{
	void *allocate(size_t sz)
	{
		return allocate(sz);
	}
	void deallocate(void *ptr)
	{
		return deallocate(ptr);
	}
};
} // namespace LMA
} // namespace Physical
} // namespace Paging

const struct LMA_t
{
} USE_LMA;
void *operator new(size_t sz, LMA_t use_lma);
void operator delete(void *ptr, LMA_t use_lma);

Changes to include/memory/page_directory.h.

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

#pragma once
#include "memory/page_table.h"
#include "memory/physical_memory.h"
#include "multiboot.h"

namespace Paging{

	struct page_table_ptr{

		union{
			char bytes[4];
			page_table* ptr;
			uint32_t value;
		};
	};
	static_assert(sizeof(page_table_ptr)==4,"");

	struct page_directory{

		page_table_ptr 	dir[1024];
		page_table		impl_table[1024];
		page_directory()
		{
			for(uint32_t p=0;p<(1<<12);p++)

				dir[p].value = 2 | (intptr_t)(new(impl_table+p) page_table(p*(1<<12)));
		}
	} __attribute__((aligned(4096)));

	uint64_t initialize(multiboot_memory_map_t* memmap, size_t len);

	namespace Physical
	{
		extern physical_layout* memory;
	}
}





|
>
|
>
|
|
|
|
|
|
|

|
>
|
|
|
|
<
>
|
|
|

|

|
|
|
|
<
>
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
#pragma once
#include "memory/page_table.h"
#include "memory/physical_memory.h"
#include "multiboot.h"

namespace Paging
{
struct page_table_ptr
{
	union {
		char bytes[4];
		page_table *ptr;
		uint32_t value;
	};
};
static_assert(sizeof(page_table_ptr) == 4, "");

struct page_directory
{
	page_table_ptr dir[1024];
	page_table impl_table[1024];
	page_directory()
	{

		for (uint32_t p = 0; p < (1 << 12); p++)
			dir[p].value = 2 | (intptr_t)(new (impl_table + p) page_table(p * (1 << 12)));
	}
} __attribute__((aligned(4096)));

uint64_t initialize(multiboot_memory_map_t *memmap, size_t len);

namespace Physical
{
extern physical_layout *memory;
}

} // namespace Paging

Changes to include/memory/page_table.h.

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
76
77
78
79

80
81
82
83
84
85
86

87
88
89
90
91
92
93

94
95
96
97
98
99
100
101
102
103

#pragma once
#include <stdint.h>
#include "buffers/container.hpp"
namespace Paging
{
	enum class page_readability{
		RO=0,


		RW=2
	};

	struct page_entry{

		union{
			char bytes[4];
			uint32_t value;
		};
		page_entry(uint32_t page_idx)
		{
			value=(page_idx<<12)|3;

		}

		bool is_present()
		{
			return value & 1;
		}
		void present(bool b)
		{
			value = b ? value | 1 : (value | 1) ^ 1;
		}

		bool is_rw()
		{
			return value & 2;
		}
		bool is_ro()
		{
			return !is_rw();
		}
		void readability(page_readability b)
		{
			value = b!=page_readability::RO ? value | 2 : (value | 2) ^ 2;
		}

		bool is_user()
		{
			return value & 4;
		}
		void user(bool b)
		{
			value = b ? value | 4 : (value | 4) ^ 4;
		}

		bool is_write_through()
		{
			return value & 8;
		}
		void write_through(bool b)
		{
			value = b ? value | 8 : (value | 8) ^ 8;
		}

		bool is_cache_enabled()
		{
			return value & 16;
		}
		void cache_enabled(bool b)
		{
			value = b ? value | 16 : (value | 16) ^ 16;
		}

		page_entry()
		{
		}
		void* ptr() const{

			return (void*)(value|0b11111111111111111111000000000000);
		}
	};
	static_assert(sizeof(page_entry)==4,"Error in page_entry size, make sure you compile for the right architecture");

	struct page_attribute{

		uint16_t p_id=0;
		char dummy[2];
	};
	static_assert(sizeof(page_attribute)%4==0,"bad alignment of page attributes");


	struct page_table{

		page_entry 		table[1024];
		page_attribute	attr[1024];
		page_table(uint32_t first_page_idx)
		{
			auto it=first_page_idx;
			auto end=first_page_idx+1024;
			for(;it<end;it++)

			{
				new(table+it) page_entry(it);
				new(attr+it) page_attribute();
			}
		}
		page_table()
		{
		}
	} __attribute__((aligned(4096)));
}





|
<
>
>
|
|

|
>
|
|
|
|
|
|
<
>
|

|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|

|
|
|
|
>
|
|
|
|

|
>
|
|
|
|

<
|
>
|
|
|
|
|
|
<
>
|
|
|
|
|
|
|
|
|
<
>
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
76
77
78
79
80
81
82
83
84
85
86
87
88

89
90
91
92
93
94
95
96

97
98
99
100
101
102
103
104
105
106

107
#pragma once
#include <stdint.h>
#include "buffers/container.hpp"
namespace Paging
{
enum class page_readability

{
	RO = 0,
	RW = 2
};

struct page_entry
{
	union {
		char bytes[4];
		uint32_t value;
	};
	page_entry(uint32_t page_idx)
	{

		value = (page_idx << 12) | 3;
	}

	bool is_present()
	{
		return value & 1;
	}
	void present(bool b)
	{
		value = b ? value | 1 : (value | 1) ^ 1;
	}

	bool is_rw()
	{
		return value & 2;
	}
	bool is_ro()
	{
		return !is_rw();
	}
	void readability(page_readability b)
	{
		value = b != page_readability::RO ? value | 2 : (value | 2) ^ 2;
	}

	bool is_user()
	{
		return value & 4;
	}
	void user(bool b)
	{
		value = b ? value | 4 : (value | 4) ^ 4;
	}

	bool is_write_through()
	{
		return value & 8;
	}
	void write_through(bool b)
	{
		value = b ? value | 8 : (value | 8) ^ 8;
	}

	bool is_cache_enabled()
	{
		return value & 16;
	}
	void cache_enabled(bool b)
	{
		value = b ? value | 16 : (value | 16) ^ 16;
	}

	page_entry()
	{
	}
	void *ptr() const
	{
		return (void *)(value | 0b11111111111111111111000000000000);
	}
};
static_assert(sizeof(page_entry) == 4, "Error in page_entry size, make sure you compile for the right architecture");

struct page_attribute
{
	uint16_t p_id = 0;
	char dummy[2];
};
static_assert(sizeof(page_attribute) % 4 == 0, "bad alignment of page attributes");


struct page_table
{
	page_entry table[1024];
	page_attribute attr[1024];
	page_table(uint32_t first_page_idx)
	{
		auto it = first_page_idx;
		auto end = first_page_idx + 1024;

		for (; it < end; it++)
		{
			new (table + it) page_entry(it);
			new (attr + it) page_attribute();
		}
	}
	page_table()
	{
	}
} __attribute__((aligned(4096)));

} // namespace Paging

Changes to include/memory/physical_memory.h.

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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323





















#pragma once
#include <stddef.h>
#include <stdint.h>
#include "buffers/extensible_buffer.hpp"

namespace Paging
{
	namespace Physical
	{

		namespace LMA{
			void initialize();
		}

		extern uint64_t physical_memory;

		template<size_t sz, bool master=true>
		struct memory_block;

		template<size_t sz>
		struct memory_block<sz, true>
		{
			bool is_free=true;
			bool is_full=false;
			bool whole=false;
			bool base=false;
			char* ptr_next=nullptr;
			uint8_t super_avail=1;
			uint8_t subs_avail=2;
			uint8_t second_subs_avail=8;
			memory_block<(sz>>2), false> main;
			memory_block<(sz>>3), false> subs[2];
			memory_block<(sz>>4), false> second_subs[8];
			constexpr memory_block(char* ptr)
			:is_free(true)
			,is_full(false)
			,super_avail(1)
			,subs_avail(2)
			,second_subs_avail(8)
			,main(ptr)
			,subs({ptr+(sz>>2), ptr+((sz>>2) + (sz>>3))})
			,second_subs({
				ptr+(sz>>1),			ptr+(sz>>1)+(sz>>4)*1,
				ptr+(sz>>1)+(sz>>4)*2,	ptr+(sz>>1)+(sz>>4)*3,
				ptr+(sz>>1)+(sz>>4)*4,	ptr+(sz>>1)+(sz>>4)*5,
				ptr+(sz>>1)+(sz>>4)*6,	ptr+(sz>>1)+(sz>>4)*7,
			})
			{}
		};

		template<size_t sz>
		struct memory_block<sz, false>
		{
			bool is_free=true;
			char* addr;
			constexpr memory_block(char* ptr)
			:is_free(true)
			,addr(ptr)
			{}
			static_assert(sz>=4096,"Bad memory block size");
		};

		template<size_t sz>
		const static memory_block<sz, false> dead_block =(char*)nullptr;

		struct physical_layout{
			size_t capacity;
			const static size_t mblock_size = (1<<16);
			const static size_t explore_limit = 64;
			ksdk::extensible_buffer<memory_block<mblock_size,true>> layout;

			size_t idx=0;
			physical_layout()
			{
				new(&layout) ksdk::extensible_buffer<memory_block<(1<<16),true>>(nullptr,nullptr);
				capacity=0;
			}
			physical_layout(char* root, size_t byte_length)
			{
				new(&layout) ksdk::extensible_buffer<memory_block<mblock_size,true>>(
					(memory_block<(1<<16)>*)root,
					(size_t)0,
					byte_length/sizeof(layout[0])
				);
			}

			void add_block(char* block_start)
			{
				layout.push_back(
					memory_block<mblock_size,true>(block_start)
				);
			}

			memory_block<(mblock_size>>2), false> get_block_m()
			{
				if(idx>=layout.size())
					idx%=layout.size();
				auto& curr=layout[idx];
				for(size_t ex=0;ex<explore_limit;ex++)
				{
					if(!curr.is_full && curr.super_avail)
					{
						--curr.super_avail;
						curr.is_free=false;
						curr.main.is_free=false;
						return curr.main;
					}
					else
					{
						++idx;
					}
				}
				return dead_block<(mblock_size>>2)>;
			}
			memory_block<(mblock_size>>3), false> get_block_s()
			{
				if(idx>=layout.size())
					idx%=layout.size();
				auto& curr=layout[idx];
				for(size_t ex=0;ex<explore_limit;ex++)
				{
					if(!curr.is_full && curr.subs_avail)
					{
						--curr.subs_avail;
						for(auto n : curr.subs)
						{
							if(n.is_free)
							{
								curr.is_free=false;
								n.is_free=false;
								return n;
							}
						}
						return dead_block<(mblock_size>>3)>;
					}
					else
					{
						++idx;
					}
				}
				return dead_block<(mblock_size>>3)>;
			}
			memory_block<(mblock_size>>4), false> get_block_ss()
			{
				if(idx>=layout.size())
					idx%=layout.size();
				auto& curr=layout[idx];
				for(size_t ex=0;ex<explore_limit;ex++)
				{
					if(!curr.is_full && curr.second_subs_avail)
					{
						--curr.second_subs_avail;
						for(auto n : curr.second_subs)
						{
							if(n.is_free)
							{
								curr.is_free=false;
								n.is_free=false;
								return n;
							}
						}
						return dead_block<(mblock_size>>4)>;
					}
					else
					{
						++idx;
					}
				}
				return dead_block<(mblock_size>>4)>;
			}

			ksdk::buffer<char> pin(char* block_ptr)
			{
				size_t rb_idx=idx;
				do{
					auto& elem=layout[rb_idx];
					if(elem.main.addr<=block_ptr && elem.second_subs[7].addr>=block_ptr) [[unlikely]]
					{
						if(elem.main.addr==block_ptr)
						{
							if(elem.whole || elem.base)
							{
								if constexpr (false)
								{
									// TODO: Handle memory errors
								}
								auto pit=rb_idx+1;
								for(;layout[pit-1].ptr_next!=nullptr;pit++);
								return ksdk::buffer<char>(elem.main.addr,(pit-rb_idx)*(mblock_size));
							}
							return ksdk::buffer<char>(elem.main.addr,mblock_size>>2);
						}
						else if(elem.subs[0].addr<=block_ptr && elem.subs[1].addr>=block_ptr)
						{
							auto b_idx=elem.subs[1].addr-block_ptr;
							return ksdk::buffer<char>(elem.subs[b_idx].addr,mblock_size>>3);
						}
						else if (elem.second_subs[0].addr<=block_ptr && elem.second_subs[7].addr>=block_ptr)
						{
							auto b_idx=elem.second_subs[7].addr-block_ptr;
							return ksdk::buffer<char>(elem.second_subs[b_idx].addr,mblock_size>>4);
						}
						return ksdk::buffer<char>(nullptr, size_t(0));
					}
					rb_idx=(rb_idx-1)%layout.size();
				}while(rb_idx!=idx);
				return ksdk::buffer<char>(nullptr, size_t(0));
			}

			bool free(char* block_ptr)
			{
				size_t rb_idx=idx;
				do{
					auto& elem=layout[rb_idx];
					if(elem.main.addr<=block_ptr && elem.second_subs[7].addr>=block_ptr) [[unlikely]]
					{
						if(elem.main.addr==block_ptr)
						{
							if(elem.whole || elem.base)
							{
								if constexpr (false)
								{
									// TODO: Handle memory errors
								}
								for(auto it=rb_idx;layout[it-1].ptr_next!=nullptr;it++)
								{
									layout[it].is_free=true;
									layout[it].is_full=false;
									layout[it].whole=false;
									layout[it].ptr_next=nullptr;
								}
								return true;
							}
							elem.main.is_free=true;
							elem.super_avail++;
							elem.is_free=elem.subs_avail==2 && elem.second_subs_avail==8;
							return true;
						}
						else if(elem.subs[0].addr<=block_ptr && elem.subs[1].addr>=block_ptr)
						{
							auto b_idx=elem.subs[1].addr-block_ptr;
							elem.subs[b_idx].is_free=true;
							elem.subs_avail++;
							elem.is_free=elem.main.is_free && elem.subs_avail==2 && elem.second_subs_avail==8;
							return true;
						}
						else if (elem.second_subs[0].addr<=block_ptr && elem.second_subs[7].addr>=block_ptr)
						{
							auto b_idx=elem.second_subs[7].addr-block_ptr;
							elem.second_subs[b_idx].is_free=true;
							elem.second_subs_avail++;
							elem.is_free=elem.main.is_free && elem.subs_avail==2 && elem.second_subs_avail==8;
							return true;
						}
						return false;
					}
					rb_idx=(rb_idx-1)%layout.size();
				}while(rb_idx!=idx);
				return false;
			}

			char* malloc(size_t sz)
			{
				if(sz<(mblock_size>>4)) [[likely]]
				{
					auto att=get_block_ss().addr;
					if(att) [[likely]]
						return att;
					att=get_block_s().addr;
					if(att)
						return att;
					att=get_block_m().addr;
					if(att)
						return att;
				}else if(sz<(mblock_size>>3))
				{
					auto att=get_block_s().addr;
					if(att) [[likely]]
						return att;
					att=get_block_m().addr;
					if(att)
						return att;
				}else if(sz<(mblock_size)>>2) [[likely]]
				{
					return get_block_m().addr;
				}else{
					if(sz%mblock_size) [[likely]]
					{
						sz=sz+mblock_size-sz%mblock_size;
						auto nbblock=sz/mblock_size;
						size_t base=0;
						for(size_t span=base;span<(layout.size()-base);span++)
						{
							if(!layout[span].is_free)
							{
								base=span+1;
							}
							if(span>0) [[likely]]
							if(layout[span-1].main.addr+mblock_size!=layout[span].main.addr) [[unlikely]]
							{
								base=span+1;
							}
							if(span-base==nbblock) [[unlikely]]
							{
								layout[base].base=true;
								for(size_t it=base;it<span;it++)
								{
									layout[it].is_free=false;
									layout[it].is_full=true;
									layout[it].whole=true;
									if(it<span-1)
										layout[it].ptr_next=layout[it+1].main.addr;
								}
								return layout[base].main.addr;
							}
						}
					}
				}
				return nullptr;
			}
		}  __attribute__((aligned(4096)));
	}
}



























|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
#pragma once
#include <stddef.h>
#include <stdint.h>
#include "buffers/extensible_buffer.hpp"

namespace Paging
{
namespace Physical
{
struct physical_layout;

extern uint64_t physical_memory;
extern physical_layout *memory;

template <size_t sz, bool master = true>
struct memory_block;

template <size_t sz>
struct memory_block<sz, true>
{
	bool is_free = true;
	bool is_full = false;
	bool whole = false;
	bool base = false;
	char *ptr_next = nullptr;
	uint8_t super_avail = 1;
	uint8_t subs_avail = 2;
	uint8_t second_subs_avail = 8;
	memory_block<(sz >> 2), false> main;
	memory_block<(sz >> 3), false> subs[2];
	memory_block<(sz >> 4), false> second_subs[8];
	constexpr memory_block(char *ptr)
		: is_free(true), is_full(false), super_avail(1), subs_avail(2), second_subs_avail(8), main(ptr), subs({ptr + (sz >> 2), ptr + ((sz >> 2) + (sz >> 3))}), second_subs({
																																									 ptr + (sz >> 1),
																																									 ptr + (sz >> 1) + (sz >> 4) * 1,
																																									 ptr + (sz >> 1) + (sz >> 4) * 2,
																																									 ptr + (sz >> 1) + (sz >> 4) * 3,
																																									 ptr + (sz >> 1) + (sz >> 4) * 4,
																																									 ptr + (sz >> 1) + (sz >> 4) * 5,
																																									 ptr + (sz >> 1) + (sz >> 4) * 6,
																																									 ptr + (sz >> 1) + (sz >> 4) * 7,
																																								 })
	{
	}
};

template <size_t sz>
struct memory_block<sz, false>
{
	bool is_free = true;
	char *addr;
	constexpr memory_block(char *ptr)
		: is_free(true), addr(ptr)
	{
	}
	static_assert(sz >= 4096, "Bad memory block size");
};

template <size_t sz>
const static memory_block<sz, false> dead_block = (char *)nullptr;
extern uint64_t physical_memory;

namespace LMA
{
void initialize();
}

extern uint64_t physical_memory;

struct physical_layout
{
	size_t capacity;
	const static size_t mblock_size = (1 << 16);
	const static size_t explore_limit = 64;
	ksdk::extensible_buffer<memory_block<mblock_size, true>> layout;

	size_t idx = 0;
	physical_layout()
	{
		new (&layout) ksdk::extensible_buffer<memory_block<(1 << 16), true>>(nullptr, nullptr);
		capacity = 0;
	}
	physical_layout(char *root, size_t byte_length)
	{
		new (&layout) ksdk::extensible_buffer<memory_block<mblock_size, true>>(
			(memory_block<(1 << 16)> *)root,
			(size_t)0,
			byte_length / sizeof(layout[0]));
	}

	void add_block(char *block_start)
	{
		layout.push_back(
			memory_block<mblock_size, true>(block_start));
	}

	memory_block<(mblock_size >> 2), false> get_block_m()
	{
		if (idx >= layout.size())
			idx %= layout.size();
		auto &curr = layout[idx];
		for (size_t ex = 0; ex < explore_limit; ex++)
		{
			if (!curr.is_full && curr.super_avail)
			{
				--curr.super_avail;
				curr.is_free = false;
				curr.main.is_free = false;
				return curr.main;
			}
			else
			{
				++idx;
			}
		}
		return dead_block<(mblock_size >> 2)>;
	}
	memory_block<(mblock_size >> 3), false> get_block_s()
	{
		if (idx >= layout.size())
			idx %= layout.size();
		auto &curr = layout[idx];
		for (size_t ex = 0; ex < explore_limit; ex++)
		{
			if (!curr.is_full && curr.subs_avail)
			{
				--curr.subs_avail;
				for (auto n : curr.subs)
				{
					if (n.is_free)
					{
						curr.is_free = false;
						n.is_free = false;
						return n;
					}
				}
				return dead_block<(mblock_size >> 3)>;
			}
			else
			{
				++idx;
			}
		}
		return dead_block<(mblock_size >> 3)>;
	}
	memory_block<(mblock_size >> 4), false> get_block_ss()
	{
		if (idx >= layout.size())
			idx %= layout.size();
		auto &curr = layout[idx];
		for (size_t ex = 0; ex < explore_limit; ex++)
		{
			if (!curr.is_full && curr.second_subs_avail)
			{
				--curr.second_subs_avail;
				for (auto n : curr.second_subs)
				{
					if (n.is_free)
					{
						curr.is_free = false;
						n.is_free = false;
						return n;
					}
				}
				return dead_block<(mblock_size >> 4)>;
			}
			else
			{
				++idx;
			}
		}
		return dead_block<(mblock_size >> 4)>;
	}

	ksdk::buffer<char> pin(char *block_ptr)
	{
		size_t rb_idx = idx;
		do
		{
			auto &elem = layout[rb_idx];
			if (elem.main.addr <= block_ptr && elem.second_subs[7].addr >= block_ptr)
				[[unlikely]] {
					if (elem.main.addr == block_ptr)
					{
						if (elem.whole || elem.base)
						{
							if constexpr (false)
							{
								// TODO: Handle memory errors
							}
							auto pit = rb_idx + 1;
							for (; layout[pit - 1].ptr_next != nullptr; pit++)
								;
							return ksdk::buffer<char>(elem.main.addr, (pit - rb_idx) * (mblock_size));
						}
						return ksdk::buffer<char>(elem.main.addr, mblock_size >> 2);
					}
					else if (elem.subs[0].addr <= block_ptr && elem.subs[1].addr >= block_ptr)
					{
						auto b_idx = elem.subs[1].addr - block_ptr;
						return ksdk::buffer<char>(elem.subs[b_idx].addr, mblock_size >> 3);
					}
					else if (elem.second_subs[0].addr <= block_ptr && elem.second_subs[7].addr >= block_ptr)
					{
						auto b_idx = elem.second_subs[7].addr - block_ptr;
						return ksdk::buffer<char>(elem.second_subs[b_idx].addr, mblock_size >> 4);
					}
					return ksdk::buffer<char>(nullptr, size_t(0));
				} rb_idx = (rb_idx - 1) % layout.size();
		} while (rb_idx != idx);
		return ksdk::buffer<char>(nullptr, size_t(0));
	}

	bool free(char *block_ptr)
	{
		size_t rb_idx = idx;
		do
		{
			auto &elem = layout[rb_idx];
			if (elem.main.addr <= block_ptr && elem.second_subs[7].addr >= block_ptr)
				[[unlikely]] {
					if (elem.main.addr == block_ptr)
					{
						if (elem.whole || elem.base)
						{
							if constexpr (false)
							{
								// TODO: Handle memory errors
							}
							for (auto it = rb_idx; layout[it - 1].ptr_next != nullptr; it++)
							{
								layout[it].is_free = true;
								layout[it].is_full = false;
								layout[it].whole = false;
								layout[it].ptr_next = nullptr;
							}
							return true;
						}
						elem.main.is_free = true;
						elem.super_avail++;
						elem.is_free = elem.subs_avail == 2 && elem.second_subs_avail == 8;
						return true;
					}
					else if (elem.subs[0].addr <= block_ptr && elem.subs[1].addr >= block_ptr)
					{
						auto b_idx = elem.subs[1].addr - block_ptr;
						elem.subs[b_idx].is_free = true;
						elem.subs_avail++;
						elem.is_free = elem.main.is_free && elem.subs_avail == 2 && elem.second_subs_avail == 8;
						return true;
					}
					else if (elem.second_subs[0].addr <= block_ptr && elem.second_subs[7].addr >= block_ptr)
					{
						auto b_idx = elem.second_subs[7].addr - block_ptr;
						elem.second_subs[b_idx].is_free = true;
						elem.second_subs_avail++;
						elem.is_free = elem.main.is_free && elem.subs_avail == 2 && elem.second_subs_avail == 8;
						return true;
					}
					return false;
				} rb_idx = (rb_idx - 1) % layout.size();
		} while (rb_idx != idx);
		return false;
	}

	char *malloc(size_t sz)
	{
		if (sz < (mblock_size >> 4)) [[likely]]
			return malloc_block_size_less_4096(sz);
		else if (sz < (mblock_size >> 3))
			[[likely]] return malloc_block_size_less_8192(sz);
		else if (sz < (mblock_size >> 2))
			[[likely]] return malloc_block_size_less_16348(sz);
		else
			return malloc_block_size_bigger_16348(sz);
	}

  private:
	inline bool size_aligns(size_t sz) 
	{
		return (sz % mblock_size) == 0; 
	}
	inline char *malloc_block_size_bigger_16348(size_t sz)
	{
		if (!size_aligns(sz))
			return nullptr;

		sz = sz + mblock_size - sz % mblock_size;
		auto nbblock = sz / mblock_size;
		size_t base = 0;
		for (size_t span = base; span < (layout.size() - base); span++)
		{
			if (!layout[span].is_free)
				base = span + 1;
			if (span > 0)
				[[likely]] if (layout[span - 1].main.addr + mblock_size !=
							   layout[span].main.addr)[[unlikely]]
				{
					base = span + 1;
				}
			if (span - base == nbblock)
				[[unlikely]] {
					layout[base].base = true;
					for (size_t it = base; it < span; it++)
					{
						layout[it].is_free = false;
						layout[it].is_full = true;
						layout[it].whole = true;
						if (it < span - 1)
							layout[it].ptr_next = layout[it + 1].main.addr;
					}
					return layout[base].main.addr;
				}
		}
	}
	inline char *malloc_block_size_less_16348(size_t sz)
	{
		return get_block_m().addr;
	}
	inline char *malloc_block_size_less_8192(size_t sz)
	{
		auto att = get_block_s().addr;
		if (att)
			[[likely]] return att;
		att = get_block_m().addr;
		if (att)
			return att;
	}
	inline char *malloc_block_size_less_4096(size_t sz)
	{
		auto att = get_block_ss().addr;
		if (att)
			[[likely]] return att;
		att = get_block_s().addr;
		if (att)
			return att;
		att = get_block_m().addr;
		if (att)
			return att;
	}
} // namespace Physical
__attribute__((aligned(4096)));
} // namespace Physical
} // namespace Paging

Changes to include/misc/includes.h.

3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdint.h>
#include <buffers/vga_buffer.h>
#include <termutils/terminal.h>
#include <bios/BDA.hpp>
#include <memory/page_directory.h>
#include <memory/physical_memory.h>
#include <asm_shims/shims.h>
#include <kstd/stl_test.h>
#include <acpi/acpi_access.h>
#include <misc/compiler_test.h>
#include <memory/lma_allocator.h>
#include <interrupts/interrupts.h>

/*included as last*/
#include <misc/init.h>
#include <misc/greeter.h>






<








3
4
5
6
7
8
9

10
11
12
13
14
15
16
17
#include <stdint.h>
#include <buffers/vga_buffer.h>
#include <termutils/terminal.h>
#include <bios/BDA.hpp>
#include <memory/page_directory.h>
#include <memory/physical_memory.h>
#include <asm_shims/shims.h>

#include <acpi/acpi_access.h>
#include <misc/compiler_test.h>
#include <memory/lma_allocator.h>
#include <interrupts/interrupts.h>

/*included as last*/
#include <misc/init.h>
#include <misc/greeter.h>

Changes to include/misc/init.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#pragma once

namespace INIT
{
void initialize(multiboot_info_t *mboot, uint32_t magic)
{
    VGA::initialize();
    Termutils::cout << "vga done\n";
    Termutils::initialize();
    Paging::Physical::LMA::initialize();
    ACPI::acpi_interface(); //HAS TO BE Initialized before Paging!!b
    Paging::initialize((multiboot_memory_map_t *)mboot->mmap_addr, mboot->mmap_length);
    Termutils::cout << "paging done\n";
    INT::initialize();
}
} // namespace INIT






<




<
<


1
2
3
4
5
6
7

8
9
10
11


12
13
#pragma once

namespace INIT
{
void initialize(multiboot_info_t *mboot, uint32_t magic)
{
    VGA::initialize();

    Termutils::initialize();
    Paging::Physical::LMA::initialize();
    ACPI::acpi_interface(); //HAS TO BE Initialized before Paging!!b
    Paging::initialize((multiboot_memory_map_t *)mboot->mmap_addr, mboot->mmap_length);


}
} // namespace INIT

Added include/misc/kernel_panic.h.




















































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#pragma once
#include "buffers/string_view"
#include "buffers/vga_buffer.h"
#include "termutils/terminal.h"

namespace Exception
{

template <class T>
void display_panic_message(T error_code)
{
    VGA::empty_vga_buffer();

    Termutils::cout << "\tCLINL - Kernel crash with error code: \n" << error_code
                    << "\n"
                    << "\n\n\tPlease report this issue at \n"
                       "https://kernel.clinl.org/ticket\nor to "
                       "[email protected]\n"
                    << "\n\n\tCLINL - The clinl foundation - 2018 \n"
                       "repository: kernel.clinl.org - MIT License\n"
                    << "\n\n\tPress the \"any\" key to shut down the Computer. "
                       "If that doesnt work, \n"
                    << "you can power off the computer safely now. \n";
}

inline void wait_until_button_press()
{
    while (true)
        ;
}

// T must have Termutils::cout_t operator<<(Termutils::cout_t, T) overloaded
template <class T>
void kernel_panic(T error_code)
{
    // 1) stop all processes
    // 2) stop all drivers
    // 3) spin down all drives
    display_panic_message(error_code);
    wait_until_button_press();
}
} // namespace Exception

Changes to include/smp/eslibk/_catchers.hpp.

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
#pragma once
#include "smp/thread.h"
#include "config.h"
#include "smp/MAGIC.hpp"

inline thread* get_threading_data_hinted(char* instack)
{
	static_assert(config::current_arch == config::arch::ix86, "Unsupported architecture");
	if constexpr (config::current_arch == config::arch::ix86)
	{
		intptr_t cursor=(intptr_t)instack;
		cursor-=cursor%(1<<12);
		uint32_t* rcursor=(uint32_t*)(cursor);
		while(rcursor[-1]!=thread_local_header || rcursor[-3]!=thread_local_trailer)
		{
			cursor-=(1<<12);
			rcursor=(uint32_t*)(cursor);
		}
		return *(thread**)((rcursor[-2]));
	}
}

inline thread* get_threading_data()
{
	char v[1];
	return get_threading_data_hinted(v);
}




|




|
|
|
|

|
|

|



|




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
#pragma once
#include "smp/thread.h"
#include "config.h"
#include "smp/MAGIC.hpp"

inline thread *get_threading_data_hinted(char *instack)
{
	static_assert(config::current_arch == config::arch::ix86, "Unsupported architecture");
	if constexpr (config::current_arch == config::arch::ix86)
	{
		intptr_t cursor = (intptr_t)instack;
		cursor -= cursor % (1 << 12);
		uint32_t *rcursor = (uint32_t *)(cursor);
		while (rcursor[-1] != thread_local_header || rcursor[-3] != thread_local_trailer)
		{
			cursor -= (1 << 12);
			rcursor = (uint32_t *)(cursor);
		}
		return *(thread **)((rcursor[-2]));
	}
}

inline thread *get_threading_data()
{
	char v[1];
	return get_threading_data_hinted(v);
}

Changes to include/termutils/terminal.h.

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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145










146
147
148
149

150
151
152
153
154
155
156
157
158
159
160
...
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
#pragma once
#include "buffers/vga_buffer.h"
#include "buffers/string_view"
#include "libk/string.h"


namespace Termutils
{

void initialize();

inline void putchar(const VGA::character character)






{
	if (VGA::text_cursor >= VGA::text_buffer.size())
	{
		auto line_minus_one = VGA::text_buffer.size() - VGA::TEXT_WIDTH;
		memmove(
			VGA::text_buffer.begin(),
			VGA::text_buffer.begin() + VGA::TEXT_WIDTH,
			line_minus_one * sizeof(VGA::character));
		VGA::text_cursor = line_minus_one;
		auto last_line = ksdk::buffer<VGA::character>(VGA::text_buffer.begin() + line_minus_one, VGA::TEXT_WIDTH);
		for (VGA::character &c : last_line)
			c = VGA::character(' ', VGA::text_color);
	}
	switch (character.c)
	{
	case '\n':
		VGA::text_buffer[VGA::text_cursor] = VGA::character(' ', character.color);
		VGA::text_cursor += VGA::TEXT_WIDTH;
		VGA::text_cursor -= VGA::text_cursor % VGA::TEXT_WIDTH;
		break;
	case '\t':
	{
		int advance = (4 - VGA::text_cursor % 4);
		auto begin = &VGA::text_buffer[VGA::text_cursor];
		auto end = begin + advance;
		for (auto it = begin; it != end; ++it)
		{
			*it = VGA::character(' ', character.color);
		}
		VGA::text_cursor += advance;
	}
	break;
	default:
		VGA::text_buffer[VGA::text_cursor] = character;
		++VGA::text_cursor;






		break;
	}
}

inline void putchar(const char c)
{
	putchar(VGA::character(c, VGA::text_color));
}

inline void write(const char *str, size_t size)
{
	auto begin = str;
	auto end = str + size;
	for (auto it = begin; it != end; ++it)
	{
		putchar(*it);
	}
}

struct endl_t
{
};

class terminal_output
{
	friend void Termutils::initialize();

  public:
	enum class int_mode
	{
		bin = 2,
		dec = 10,
		hex = 16
	};
	int_mode mode;
	template <typename T>
	terminal_output &operator<<(const T number)
	{
		const int local_size = 64;
		static char local[local_size] = {};
		static const char digits[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
		int base = (int)mode;
		auto degree = 1;
		int sign = 1;
		if ((T)(-1) < 0)
		{
			auto trem = number;
			sign = trem < 0 ? -1 : 1;
			unsigned long long rem;
			if (base == 10)
				rem = trem * sign;
			else
				rem = (unsigned long long)trem;
			do
			{
				auto degrad = rem % base;
				local[local_size - degree] = digits[degrad];
				rem -= degrad;
				rem = rem / base;
				degree++;
			} while (rem != 0);
		}
		else
		{
			auto rem = number;
			do
			{
				int degrad = rem % base;
				local[local_size - degree] = digits[degrad];
				rem -= degrad;
				rem /= base;
				degree++;
			} while (rem != 0);
		}
		if (sign == -1 && base == 10)
		{
			local[local_size - degree] = '-';
			degree++;
		}
		else if (base == 2)
		{
			local[local_size - degree] = 'b';
			degree++;
			local[local_size - degree] = '0';
			degree++;
		}
		else if (base == 16)
		{
			local[local_size - degree] = 'x';
			degree++;
			local[local_size - degree] = '0';
			degree++;
		}
		Termutils::write(local + local_size - degree + 1, degree - 1);
		return *this;
	}
};

extern terminal_output cout;
extern size_t tab_size;
extern endl_t endl;










} // namespace Termutils

template <>
Termutils::terminal_output &Termutils::terminal_output::operator<<(ksdk::string_view s);

template <>
inline Termutils::terminal_output &Termutils::terminal_output::operator<<(Termutils::endl_t)
{
	Termutils::putchar('\n');
	return *this;
}
template <>
inline Termutils::terminal_output &Termutils::terminal_output::operator<<(bool b)
{
	static const char *true_str = "true";
	static const char *false_str = "false";
................................................................................
template <>
inline Termutils::terminal_output &Termutils::terminal_output::operator<<(const char *v)
{
	Termutils::write(v, strlen(v));
	return *this;
}
template <>
inline Termutils::terminal_output &Termutils::terminal_output::operator<<(Termutils::terminal_output::int_mode n)
{
	this->mode = n;
	return *this;
}
template <>
inline Termutils::terminal_output &Termutils::terminal_output::operator<<(VGA::color_mode n)
{
	VGA::text_color = n;
	return *this;
}



>
>



|

|
>
>
>
>
>
>



|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>
>
>
>
>



>







|
|
<
<
|
<











|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>
>
>
>
>
>
>
>
>




>



|







 







|

|








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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
...
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
#pragma once
#include "buffers/vga_buffer.h"
#include "buffers/string_view"
#include "libk/string.h"
#include "kstd/type_traits.hpp"

namespace Termutils
{

extern void initialize();

inline void fill_columns(size_t columns, const VGA::character to_fill)
{
	for (int i = 0; i < columns; i++)
		VGA::text_buffer[VGA::text_cursor++] = to_fill;
}

inline void handle_line_overflows()
{
	if (VGA::text_cursor >= VGA::text_buffer.size())
	{
		size_t line_minus_one = VGA::text_buffer.size() - VGA::TEXT_WIDTH;
		memmove(VGA::text_buffer.begin(), VGA::text_buffer.begin() + VGA::TEXT_WIDTH, line_minus_one * sizeof(VGA::character));
		VGA::text_cursor = line_minus_one;
		fill_columns(VGA::TEXT_WIDTH, VGA::character(' ', VGA::make_color_mode(VGA::color::BLACK, VGA::color::BLACK)));
		VGA::text_cursor = line_minus_one;
	}
}

inline void put_new_line(const VGA::color_mode color)
{
	fill_columns(VGA::TEXT_WIDTH - (VGA::text_cursor % VGA::TEXT_WIDTH), VGA::character(' ', color));
}

extern size_t tab_size;
inline void put_tabulator(const VGA::color_mode color)
{
	fill_columns(tab_size, VGA::character(' ', color));
}

inline bool put_pure_char(const VGA::character character)
{
	VGA::text_buffer[VGA::text_cursor] = character;
	++VGA::text_cursor;
}

inline void putchar(const VGA::character character)
{
	handle_line_overflows();
	switch (character.c)
	{
	case '\n':
		put_new_line(character.color);
		break;
	case '\t':
		put_tabulator(character.color);
		break;
	default:
		put_pure_char(character);
		break;
	}
}

inline void putchar(const char c)
{
	putchar(VGA::character(c, VGA::text_color));
}

inline void write(const char *str, size_t size)
{
	ksdk::buffer<const char> to_print(str, size);
	for (const auto &i : to_print)


		putchar(i);

}

struct endl_t
{
};

class terminal_output
{
	friend void Termutils::initialize();

  public:
	struct int_mode
	{
		const static char bin = 2;
		const static char dec = 10;
		const static char hex = 16;
	};
	static constexpr char digits[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
	static constexpr char character_buffer_size = 64;
	char representation_base;
	char character_buffer[character_buffer_size] = {};
	char position_in_buffer = 1;
	char sign = 1;

	void reset_variables()
	{
		position_in_buffer = 1;
		sign = 1;
	}

	void append_char_to_buffer(char to_append)
	{
		character_buffer[character_buffer_size - position_in_buffer] = to_append;
		position_in_buffer++;
	}

	void add_base_signs()
	{
		if (sign == -1 && representation_base == 10)
		{
			append_char_to_buffer('-');
		}
		else if (representation_base == 2)
		{
			append_char_to_buffer('b');
			append_char_to_buffer('0');
		}
		else if (representation_base == 16)
		{
			append_char_to_buffer('x');
			append_char_to_buffer('0');
		}
	}

	template <class T>
	inline void parse_number(T remainder, typename kstd::enable_if<kstd::is_unsigned<T>::value, char>::type = 0)
	{
		do
		{
			char degrad = remainder % representation_base;
			append_char_to_buffer(digits[degrad]);
			remainder -= degrad;
			remainder /= representation_base;
		} while (remainder != 0);
	}

	template <class T>
	inline void parse_number(const T number, typename kstd::enable_if<!kstd::is_unsigned<T>::value, char>::type = 0)
	{
		sign = number < 0 ? -1 : 1;
		parse_number<unsigned long long int>(number * sign);
	}

	template <class T>
	terminal_output &operator<<(const T number)
	{
		typename kstd::enable_if<kstd::is_integral<T>::value, char>::type prevent_non_integral_types = 0;
		reset_variables();
		parse_number(number);
		add_base_signs();

		Termutils::write(character_buffer + character_buffer_size - position_in_buffer + 1, position_in_buffer - 1);
		return *this;
	}
};

extern terminal_output cout;
extern size_t tab_size;
extern endl_t endl;
extern VGA::color_mode cl_error;
extern VGA::color_mode cl_success;
extern VGA::color_mode cl_text;
extern VGA::color_mode cl_passive;
extern VGA::color_mode cl_info;
} // namespace Termutils

template <>
Termutils::terminal_output &Termutils::terminal_output::operator<<(ksdk::string_view s);

template <>
inline Termutils::terminal_output &Termutils::terminal_output::operator<<(Termutils::endl_t)
{
	Termutils::put_new_line(VGA::text_color);
	return *this;
}
template <>
inline Termutils::terminal_output &Termutils::terminal_output::operator<<(bool b)
{
	static const char *true_str = "true";
	static const char *false_str = "false";
................................................................................
template <>
inline Termutils::terminal_output &Termutils::terminal_output::operator<<(const char *v)
{
	Termutils::write(v, strlen(v));
	return *this;
}
template <>
inline Termutils::terminal_output &Termutils::terminal_output::operator<<(char n)
{
	this->representation_base = n;
	return *this;
}
template <>
inline Termutils::terminal_output &Termutils::terminal_output::operator<<(VGA::color_mode n)
{
	VGA::text_color = n;
	return *this;
}

Deleted include/testing/testing.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
using namespace Termutils;

void REQUIRE (bool state, const char* name) { //unit testing function
	auto color_std= VGA::make_color_mode(VGA::color::WHITE);
	auto color_tst= VGA::make_color_mode (VGA::color::CYAN);
	auto color_em= VGA::make_color_mode(VGA::color::GREEN);
	auto color_err= VGA::make_color_mode(VGA::color::RED);
		
	if (state) {
		//in case you want to print the working test-cases
		//cout << color_em << " OK \n" << color_std;
	} else {
		cout << "\t\t" << color_tst << name << ":";
		cout << color_err << " BAD \n" << color_std;
	}
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























Added include/tests/acpi_tests/wrapper_test.hpp.
































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#pragma once
#include "acpi/wrappers.h"
#include "tests/test_utils.hpp"

namespace TH
{
namespace ACPI_TEST
{
extern test_result tr;

struct TEST_WRAPPERS
{
    void test_get_rsdp()
    {
        char *sig = (char *)ACPI::UTILS::find_rsdp();
        if (sig == nullptr)
            return;
        tr.assert(memcmp(sig, "RSD PTR ", 8) == 0, "test_get_rsdp");
    }
    void test_correct_table_checksum()
    {
        struct test_struct
        {
            uint8_t a = 254;
            uint8_t b = 1;
            uint8_t c = 1;
            uint8_t d = 0;
        } __attribute__((packed));
        test_struct object;
        tr.assert(ACPI::UTILS::correct_table_checksum(&object),
                  "test_correct_table_checksum");
    }
    void test_check_for_correct_rsdp()
    {
        ACPI::SDT::RSDP *temporary = ACPI::UTILS::find_rsdp();
        if (!ACPI::UTILS::correct_table_checksum(temporary))
            return;
        tr.assert(ACPI::UTILS::check_for_correct_rsdp((ACPI::sign_8_type *)temporary), "test_check_for_correct_rsdp");
    }
    TEST_WRAPPERS()
    {
        test_get_rsdp();
        test_correct_table_checksum();
        test_check_for_correct_rsdp();
    }
};
} // namespace ACPI_TEST
} // namespace TH

Added include/tests/ksdk_tests/buffer_test.hpp.










































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#pragma once
#include "tests/test_utils.hpp"

namespace TH::KSDK_TEST
{
extern test_result tr;
class BUFFER_TEST
{
  public:
    BUFFER_TEST()
    {
        int a[20];
        ksdk::buffer<int> test_buffer(a, 20);
        tr.assert(test_buffer.size() == 20, "BUFFER_TEST 1");
        for (auto &i : test_buffer)
            i = 10;
        for (const auto &i : test_buffer)
            tr.assert(i == 10, "BUFFER_TEST 2");
    }
};
} // namespace TH::KSDK_TEST

Added include/tests/ksdk_tests/memory_test.hpp.




























>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#pragma once
#include "tests/test_utils.hpp"

namespace TH::KSDK_TEST
{
extern test_result tr;
class MEMORY_TEST
{
  public:
    MEMORY_TEST()
    {
    }
};
} // namespace TH::KSDK_TEST

Added include/tests/ksdk_tests/sosa_tree_tests.hpp.




































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#pragma once
#include "buffers/sosa_tree.hpp"
#include "termutils/terminal.h"
#include "tests/test_utils.hpp"

namespace TH::KSDK_TEST
{

extern test_result tr;

void dump_sosa_tree(ksdk::sosa_tree<int> tree)
{
    for (auto i : tree.buffer())
    {
        if (i.set)
            Termutils::cout << i.elem << ",";
        else
            Termutils::cout << "_"
                            << ",";
    }
    Termutils::cout << Termutils::endl;
}

void SOSA_TREE_TEST()
{
    ksdk::sosa_tree<int> tree(5);
    tree.insert(4);
    tree.insert(2);
    tree.insert(6);
    tree.insert(1);
    tree.insert(5);
    tree.insert(3);
    tree.insert(7);

    auto it = tree.find(7);
    tr.assert(it.pos != 0, "SOSA_TREE_TEST 1");

    it = tree.find(5);
    ++it;
    tr.assert(*it == 6, "SOSA_TREE_TEST 2");

    it = tree.find(5);
    tree.remove(it.pos);
    it = tree.find(4);
    ++it;
    tr.assert(*it == 6, "SOSA_TREE_TEST 3");

    tr.execute_if_failed(dump_sosa_tree, tree);
}
} // namespace TH::KSDK_TEST

Added include/tests/stl_tests/type_trait_tests.hpp.
































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
#pragma once
#include "kstd/type_traits.hpp"

namespace TH::KSTD_TEST
{

extern test_result tr;

class TYPE_TRAITS_TEST
{

    void test_integral_contants()
    {
        kstd::integral_constant<int, 0xC0FFEE> a;
        tr.assert(a.value == 0xC0FFEE, "Correct Value");
    }

    struct test_is_void
    {
        kstd::is_void<void> void_elem;
        kstd::is_void<const volatile void> const_volatile_void_elem;
        kstd::is_void<volatile void> volatile_void_elem;
        kstd::is_void<const void> const_void_elem;
        kstd::is_void<int> non_void_elem;
        test_is_void()
        {
            tr.assert(void_elem.value == true, "Correctly find void");
            tr.assert(non_void_elem.value == false, "Don't trigger for non-void");
            tr.assert(const_volatile_void_elem.value == true, "const volatile void");
            tr.assert(volatile_void_elem.value == true, "volatile void");
            tr.assert(const_void_elem.value == true, "const void");
        }
    };

    void test_remove_const()
    {
        typename kstd::remove_const<const int>::type a = 10;
        a = 11;
        typename kstd::remove_const<int>::type b = 10;
        b = 100;
        tr.assert(a == 11, "Removed const");
        tr.assert(b == 100, "Kept unconstness");
    }

    void test_remove_volatile()
    {
        typedef kstd::remove_volatile<volatile int>::type volatile_int;
        typedef kstd::remove_volatile<int>::type non_volatile_int;
        tr.assert(kstd::is_same<volatile_int, int>::value == true, "Removed volatile");
        tr.assert(kstd::is_same<non_volatile_int, int>::value == true, "Kept non-volatility volatile");
    }

    void test_remove_cv()
    {
        typedef kstd::remove_cv<const volatile int>::type const_volatile_int;
        tr.assert(kstd::is_same<const_volatile_int, int>::value == true, "Removed volatile and const ");
    }

    void test_add_const()
    {
        typedef kstd::add_const<int>::type test_int;
        tr.assert(kstd::is_same<test_int, const int>::value == true, "added const ");
    }

    void test_add_volatile()
    {
        typedef kstd::add_volatile<int>::type test_int;
        tr.assert(kstd::is_same<test_int, volatile int>::value == true, "added volatile ");
    }

    void test_add_cv()
    {
        typedef kstd::add_cv<int>::type test_int;
        tr.assert(kstd::is_same<test_int, const volatile int>::value == true, "added cv ");
    }

    void test_remove_reference()
    {
        typedef kstd::remove_reference<int>::type test_int;
        typedef kstd::remove_reference<int &>::type test_int_ref;
        typedef kstd::remove_reference<int &&>::type test_int_dref;
        tr.assert(kstd::is_same<test_int, int>::value == true, "nonref stayed non ref");
        tr.assert(kstd::is_same<test_int_ref, int>::value == true, "removed ref");
        tr.assert(kstd::is_same<test_int_dref, int>::value == true, "removed double ref");
    }

    void test_add_reference()
    {
        typedef kstd::add_reference<int>::type test_int;
        tr.assert(kstd::is_same<test_int, int &>::value == true, "added ref");
    }

    void test_remove_pointer()
    {
        typedef kstd::remove_pointer<int>::type test_int;
        typedef kstd::remove_pointer<int *>::type test_int_ptr;
        typedef kstd::remove_pointer<int *>::type test_int_dptr;
        tr.assert(kstd::is_same<test_int, int>::value == true, "nonref stayed nonptr");
        tr.assert(kstd::is_same<test_int_ptr, int>::value == true, "removed ptr");
        tr.assert(kstd::is_same<test_int_dptr, int>::value == true, "removed double ptr");
    }

    void test_add_pointer()
    {
        typedef kstd::add_pointer<int>::type test_int;
        tr.assert(kstd::is_same<test_int, int *>::value == true, "added ptr");
    }

    void test_remove_extent()
    {
        typedef kstd::remove_extent<int>::type test_int;
        typedef kstd::remove_extent<int[]>::type test_int_ext;
        typedef kstd::remove_extent<int[10]>::type test_int_vext;
        tr.assert(kstd::is_same<test_int, int>::value == true, "nonext stayed nonext");
        tr.assert(kstd::is_same<test_int_ext, int>::value == true, "removed ext");
        tr.assert(kstd::is_same<test_int_vext, int>::value == true, "removed val ext");
    }

    void test_remove_all_extents()
    {
        typedef kstd::remove_all_extents<int>::type test_int;
        typedef kstd::remove_all_extents<int[]>::type test_int_ext;
        typedef kstd::remove_all_extents<int[10]>::type test_int_vext;
        typedef kstd::remove_all_extents<int[][1][10]>::type test_int_double_ext;
        typedef kstd::remove_all_extents<int[10][10]>::type test_int_double_dext;
        tr.assert(kstd::is_same<test_int, int>::value == true, "nonext stayed nonext");
        tr.assert(kstd::is_same<test_int_ext, int>::value == true, "removed ext");
        tr.assert(kstd::is_same<test_int_vext, int>::value == true, "removed val ext");
        tr.assert(kstd::is_same<test_int_double_ext, int>::value == true, "removed double ext");
        tr.assert(kstd::is_same<test_int_double_dext, int>::value == true, "removed double val ext");
    }

    void test_aligned_storage()
    {
        int typesize = sizeof(kstd::aligned_storage<6, 8>::type);
        tr.assert(typesize == 8, "Correctly alligned");
    }

    void test_is_integral_base()
    {
        bool non_integral = kstd::is_integral_base<float>::value;
        bool integral_bool = kstd::is_integral_base<bool>::value;
        bool integral_signed_char = kstd::is_integral_base<signed char>::value;
        bool integral_unsigned_char = kstd::is_integral_base<unsigned char>::value;
        bool integral_wchar = kstd::is_integral_base<wchar_t>::value;
        bool integral_short = kstd::is_integral_base<short>::value;
        bool integral_int = kstd::is_integral_base<int>::value;
        bool integral_long = kstd::is_integral_base<long>::value;
        bool integral_long_long = kstd::is_integral_base<long long>::value;
        bool integral_unsigned_short = kstd::is_integral_base<unsigned short>::value;
        bool integral_unsigned_int = kstd::is_integral_base<unsigned int>::value;
        bool integral_unsigned_long = kstd::is_integral_base<unsigned long>::value;
        bool integral_unsigned_long_long = kstd::is_integral_base<unsigned long long>::value;
        tr.assert(non_integral == false, "test_is_integral_base");
        tr.assert(integral_bool, "test_is_integral_base");
        tr.assert(integral_signed_char, "test_is_integral_base");
        tr.assert(integral_unsigned_char, "test_is_integral_base");
        tr.assert(integral_wchar, "test_is_integral_base");
        tr.assert(integral_short, "test_is_integral_base");
        tr.assert(integral_int, "test_is_integral_base");
        tr.assert(integral_long, "test_is_integral_base");
        tr.assert(integral_long_long, "test_is_integral_base");
        tr.assert(integral_unsigned_short, "test_is_integral_base");
        tr.assert(integral_unsigned_int, "test_is_integral_base");
        tr.assert(integral_unsigned_long, "test_is_integral_base");
        tr.assert(integral_unsigned_long_long, "test_is_integral_base");
    }

    void test_is_integral()
    {
        bool non_integral = kstd::is_integral<float>::value;
        bool integral_bool = kstd::is_integral<const bool>::value;
        bool integral_signed_char = kstd::is_integral<volatile signed char>::value;
        bool integral_unsigned_char = kstd::is_integral<const volatile unsigned char>::value;
        bool integral_wchar = kstd::is_integral<wchar_t>::value;
        bool integral_short = kstd::is_integral<short>::value;
        bool integral_int = kstd::is_integral<int>::value;
        bool integral_long = kstd::is_integral<long>::value;
        bool integral_long_long = kstd::is_integral<long long>::value;
        bool integral_unsigned_short = kstd::is_integral<unsigned short>::value;
        bool integral_unsigned_int = kstd::is_integral<unsigned int>::value;
        bool integral_unsigned_long = kstd::is_integral<unsigned long>::value;
        bool integral_unsigned_long_long = kstd::is_integral<unsigned long long>::value;
        tr.assert(non_integral == false, "test_is_integral");
        tr.assert(integral_bool, "test_is_integral");
        tr.assert(integral_signed_char, "test_is_integral");
        tr.assert(integral_unsigned_char, "test_is_integral");
        tr.assert(integral_wchar, "test_is_integral");
        tr.assert(integral_short, "test_is_integral");
        tr.assert(integral_int, "test_is_integral");
        tr.assert(integral_long, "test_is_integral");
        tr.assert(integral_long_long, "test_is_integral");
        tr.assert(integral_unsigned_short, "test_is_integral");
        tr.assert(integral_unsigned_int, "test_is_integral");
        tr.assert(integral_unsigned_long, "test_is_integral");
        tr.assert(integral_unsigned_long_long, "test_is_integral");
    }

    void test_is_floating_point_base()
    {
        bool non_floating_point = kstd::is_floating_point_base<int>::value;
        bool fp_float = kstd::is_floating_point_base<float>::value;
        bool fp_double = kstd::is_floating_point_base<double>::value;
        bool fp_long_double = kstd::is_floating_point_base<long double>::value;
        tr.assert(non_floating_point == false, "test_is_integral_base");
        tr.assert(fp_float, "test_is_integral_base");
        tr.assert(fp_double, "test_is_integral_base");
        tr.assert(fp_long_double, "test_is_integral_base");
    }

    void test_is_floating_point()
    {
        bool non_floating_point = kstd::is_floating_point<int>::value;
        bool fp_float = kstd::is_floating_point<volatile float>::value;
        bool fp_double = kstd::is_floating_point<const double>::value;
        bool fp_long_double = kstd::is_floating_point<const volatile long double>::value;
        tr.assert(non_floating_point == false, "test_is_integral_base");
        tr.assert(fp_float, "test_is_integral_base");
        tr.assert(fp_double, "test_is_integral_base");
        tr.assert(fp_long_double, "test_is_integral_base");
    }

    void test_is_array()
    {
        bool non_array = kstd::is_array<int>::value;
        bool array_1 = kstd::is_array<int[]>::value;
        bool array_2 = kstd::is_array<int[10]>::value;
        tr.assert(non_array == false, "test_is_array");
        tr.assert(array_1, "test_is_array");
        tr.assert(array_2, "test_is_array");
    }

    void test_is_pointer()
    {
        bool non_ptr = kstd::is_pointer<int>::value;
        bool ptr = kstd::is_pointer<int *>::value;
        tr.assert(non_ptr == false, "test_is_array");
        tr.assert(ptr, "test_is_array");
    }

    void test_is_arithmetic()
    {
        class a
        {
        };
        bool non_arith = kstd::is_arithmetic<a>::value;
        bool arith1 = kstd::is_arithmetic<int>::value;
        bool arith2 = kstd::is_arithmetic<double>::value;
        tr.assert(non_arith == false, "test_is_arithmetic");
        tr.assert(arith1, "test_is_arithmetic");
        tr.assert(arith2, "test_is_arithmetic");
    }

    void test_is_fundamental()
    {
        class a
        {
        };
        bool non_fund = kstd::is_fundamental<a>::value;
        bool fund1 = kstd::is_fundamental<int>::value;
        bool fund2 = kstd::is_fundamental<double>::value;
        bool fund3 = kstd::is_fundamental<void>::value;
        tr.assert(non_fund == false, "test_is_fundamental");
        tr.assert(fund1, "test_is_fundamental");
        tr.assert(fund2, "test_is_fundamental");
        tr.assert(fund3, "test_is_fundamental");
    }

    void test_is_const()
    {
        tr.assert(kstd::is_const<const int>::value == true, "test_is_const");
        tr.assert(kstd::is_const<int>::value == false, "test_is_const");
    }

    void test_is_reference()
    {
        tr.assert(kstd::is_reference<int &>::value == true, "test_is_reference");
        tr.assert(kstd::is_reference<int>::value == false, "test_is_reference");
    }

    void test_is_function()
    {
        tr.assert(kstd::is_function<int>::value == false, "test_is_function");
        tr.assert(kstd::is_function<void(void)>::value == true, "test_is_function");
    }

    void test_is_object()
    {
        class a
        {
        };
        bool obj = kstd::is_object<a>::value;
        bool non_obj1 = kstd::is_object<int &>::value;
        bool non_obj2 = kstd::is_object<void(void)>::value;
        bool non_obj3 = kstd::is_object<void>::value;
        tr.assert(obj, "test_is_object");
        tr.assert(non_obj1 == false, "test_is_object");
        tr.assert(non_obj2 == false, "test_is_object");
        tr.assert(non_obj3 == false, "test_is_object");
    }

    void test_is_class()
    {
        class a
        {
        };
        union b {
        };
        tr.assert(kstd::is_class<a>::value == true, "test_is_class");
        tr.assert(kstd::is_class<b>::value == false, "test_is_class");
        tr.assert(kstd::is_class<int>::value == false, "test_is_class");
    }

    void test_is_union()
    {
        class a
        {
        };
        union b {
        };
        tr.assert(kstd::is_union<a>::value == false, "test_is_union");
        tr.assert(kstd::is_union<b>::value == true, "test_is_union");
        tr.assert(kstd::is_union<int>::value == false, "test_is_union");
    }

    void test_is_enum()
    {
        class a
        {
        };
        union b {
        };
        enum c
        {
        };
        tr.assert(kstd::is_enum<a>::value == false, "test_is_enum");
        tr.assert(kstd::is_enum<b>::value == false, "test_is_enum");
        tr.assert(kstd::is_enum<c>::value == true, "test_is_enum");
        tr.assert(kstd::is_enum<int>::value == false, "test_is_enum");
    }

    void test_is_member_function_pointer()
    {
        struct a
        {
            void b()
            {
            }
            void c()
            {
            }
        };
        tr.assert(kstd::is_member_function_pointer<a>::value == false, "is_member_function_pointer");
        tr.assert(kstd::is_member_function_pointer<decltype(&a::b)>::value == false, "is_member_function_pointer");
        tr.assert(kstd::is_member_function_pointer<int>::value == false, "is_member_function_pointer");
    }
    void test_is_member_object_pointer()
    {
        struct a
        {
            int a, d;
            void b()
            {
            }
            void c()
            {
            }
        };
        tr.assert(kstd::is_member_object_pointer<a>::value == false, "is_member_function_pointer 1 ");
        tr.assert(kstd::is_member_object_pointer<int a::*>::value, "is_member_function_pointer 2 ");
        tr.assert(kstd::is_member_object_pointer<decltype(&a::c)>::value == false, "is_member_function_pointer 3 ");
    }

    void test_is_scalar()
    {
        class a
        {
          public:
            int a;
        };
        enum b
        {
        };
        tr.assert(kstd::is_scalar<int>::value, "test_is_scalar 1");
        tr.assert(kstd::is_scalar<b>::value, "test_is_scalar 2");
        tr.assert(kstd::is_scalar<a>::value == false, "test_is_scalar 3");
        tr.assert(kstd::is_scalar<int(a::*)>::value, "test_is_scalar 4");
        tr.assert(kstd::is_scalar<int *>::value, "test_is_scalar 5");
    }

    void test_is_member_pointer()
    {
        class A
        {
          public:
            int a;
        };
        tr.assert(kstd::is_member_pointer<int A::*>::value == true, "test_is_member_pointer 1");
        tr.assert(kstd::is_member_pointer<int>::value == false, "test_is_member_pointer 2");
    }

    void test_is_volatile()
    {
        tr.assert(kstd::is_volatile<int>::value == false, "test_is_volatile");
        tr.assert(kstd::is_volatile<volatile int>::value, "test_is_volatile");
    }

    void test_is_pod()
    {
        class a
        {
            int a, b, c;
        };
        class b
        {
            b() {}
            void a() {}
        };
        tr.assert(kstd::is_pod<a>::value == true, "test_is_pod 1");
        tr.assert(kstd::is_pod<b>::value == false, "test_is_pod 2");
    }

    void test_is_empty()
    {
        class a
        {
            int a, b, c;
        };
        class b
        {
        };
        tr.assert(kstd::is_empty<a>::value == false, "test_is_empty 1");
        tr.assert(kstd::is_empty<b>::value == true, "test_is_empty 2");
    }

    void test_is_polymorphic()
    {
        class a
        {
            virtual int something() = 0;
        };
        class b : a
        {
            int something()
            {
            }
        };
        class c
        {
            int a;
        };
        tr.assert(kstd::is_polymorphic<a>::value == true, "test_is_polymorphic 1");
        tr.assert(kstd::is_polymorphic<b>::value == true, "test_is_polymorphic 2");
        tr.assert(kstd::is_polymorphic<c>::value == false, "test_is_polymorphic 3");
    }
    void test_is_abstract()
    {
        class a
        {
            virtual int something() = 0;
        };
        class b : a
        {
            int something()
            {
            }
        };
        class c
        {
            int a;
        };
        tr.assert(kstd::is_abstract<a>::value == true, "test_is_abstract 1");
        tr.assert(kstd::is_abstract<b>::value == false, "test_is_abstract 2");
        tr.assert(kstd::is_abstract<c>::value == false, "test_is_abstract 3");
    }

    void test_has_trivial_constructor()
    {
        class a
        {
        };
        class b
        {
            b()
            {
            }
        };
        tr.assert(kstd::has_trivial_constructor<a>::value == true, "test_has_trivial_constructor 1");
        tr.assert(kstd::has_trivial_constructor<b>::value == false, "test_has_trivial_constructor 2");
    }

    void test_has_trivial_copy()
    {
        class a
        {
        };
        class b
        {
            b(b &other)
            {
            }
        };
        tr.assert(kstd::has_trivial_copy<a>::value == true, "test_has_trivial_copy 1");
        tr.assert(kstd::has_trivial_copy<b>::value == false, "test_has_trivial_copy 2");
    }

    void test_has_trivial_assign()
    {
        class a
        {
        };
        class b
        {
            void operator=(b &other)
            {
            }
        };
        tr.assert(kstd::has_trivial_assign<a>::value == true, "test_has_trivial_assign 1");
        tr.assert(kstd::has_trivial_assign<b>::value == false, "test_has_trivial_assign 2");
    }

    void test_has_trivial_destructor()
    {
        class a
        {
        };
        class b
        {
            ~b()
            {
            }
        };
        tr.assert(kstd::has_trivial_destructor<a>::value == true, "test_has_trivial_destructor 1");
        tr.assert(kstd::has_trivial_destructor<b>::value == false, "test_has_trivial_destructor 2");
    }

    void test_has_nothrow_constructor()
    {
        class a
        {
            a()
            {
            }
        };
        class b
        {
            b nothrow()
            {
            }
        };
        tr.assert(kstd::has_nothrow_constructor<a>::value == false, "test_has_trivial_destructor 1");
        tr.assert(kstd::has_nothrow_constructor<b>::value == true, "test_has_trivial_destructor 2");
    }

    void test_has_nothrow_copy()
    {
        class a
        {
            a(a &other)
            {
            }
        };
        class b
        {
            b nothrow(b &other)
            {
            }
        };
        tr.assert(kstd::has_nothrow_copy<a>::value == false, "test_has_nothrow_copy 1");
        tr.assert(kstd::has_nothrow_copy<b>::value == true, "test_has_nothrow_copy 2");
    }

    void test_has_nothrow_assign()
    {
        class a
        {
            void operator=(a &other)
            {
            }
        };
        class b
        {
            void operator=(b &other) noexcept
            {
            }
        };
        tr.assert(kstd::has_nothrow_assign<a>::value == false, "test_has_nothrow_assign 1");
        tr.assert(kstd::has_nothrow_assign<b>::value == true, "test_has_nothrow_assign 2");
    }

    void test_has_virtual_destructor()
    {
        class a
        {
          public:
            virtual ~a() = 0;
        };
        class b : a
        {
          public:
            ~b()
            {
            }
        };
        class c
        {
        };
        tr.assert(kstd::has_virtual_destructor<a>::value == true, "test_has_virtual_destructor 1");
        tr.assert(kstd::has_virtual_destructor<b>::value == true, "test_has_virtual_destructor 2");
        tr.assert(kstd::has_virtual_destructor<c>::value == false, "test_has_virtual_destructor 3");
    }

    void test_is_signed()
    {
        tr.assert(kstd::is_signed<void>::value == false, "test_is_signed");
        tr.assert(kstd::is_signed<signed char>::value, "test_is_signed");
        tr.assert(kstd::is_signed<short>::value, "test_is_signed");
        tr.assert(kstd::is_signed<int>::value, "test_is_signed");
        tr.assert(kstd::is_signed<long>::value, "test_is_signed");
        tr.assert(kstd::is_signed<long long>::value, "test_is_signed");
    }

    void test_is_unsigned()
    {
        tr.assert(kstd::is_unsigned<void>::value == false, "test_is_unsigned");
        tr.assert(kstd::is_unsigned<signed char>::value == false, "test_is_unsigned");
        tr.assert(kstd::is_unsigned<unsigned char>::value, "test_is_unsigned");
        tr.assert(kstd::is_unsigned<unsigned short>::value, "test_is_unsigned");
        tr.assert(kstd::is_unsigned<unsigned int>::value, "test_is_unsigned");
        tr.assert(kstd::is_unsigned<unsigned long>::value, "test_is_unsigned");
        tr.assert(kstd::is_unsigned<unsigned long long>::value, "test_is_unsigned");
    }

    void test_alignment_of()
    {
        tr.assert(kstd::alignment_of<int>::value == 4, "test_alignment_of 1");
        tr.assert(kstd::alignment_of<char>::value == 1, "test_alignment_of 2");
        tr.assert(kstd::alignment_of<float>::value == 4, "test_alignment_of 3");
    }

    void test_rank()
    {
        tr.assert(kstd::rank<int>::value == 0, "test_rank 1");
        tr.assert(kstd::rank<int[]>::value == 1, "test_rank 2");
        tr.assert(kstd::rank<int[][40][40][12]>::value == 4, "test_rank 3");
    }

    void test_extent()
    {
        tr.assert(kstd::extent<int>::value == 0, "test_extent 1");
        tr.assert(kstd::extent<int[]>::value == 0, "test_extent 2");
        tr.assert(kstd::extent<int[][40][40][12], 3>::value == 12, "test_extent 3");
        tr.assert(kstd::extent<int[][40][40][12], 1>::value == 40, "test_extent 4");
    }

    void test_is_convertible()
    {
        class Base
        {
          public:
            explicit Base(int) {}
        };

        class D : public Base
        {
          public:
            explicit D(int i) : Base(i) {}
        };
        class a
        {
        };
        tr.assert(kstd::is_convertible<a, int>::value == false, "test_is_convertible 1");
        tr.assert(kstd::is_convertible<char, int>::value, "test_is_convertible 2");
        tr.assert(kstd::is_convertible<D, Base>::value, "test_is_convertible 3");
    }

    void test_is_base_of()
    {
        class a
        {
        };
        class b : a
        {
        };
        class c
        {
        };
        tr.assert(kstd::is_base_of<a, b>::value == true, "test_is_base_of");
        tr.assert(kstd::is_base_of<a, c>::value == false, "test_is_base_of");
        tr.assert(kstd::is_base_of<b, c>::value == false, "test_is_base_of");
    }

  public:
    TYPE_TRAITS_TEST()
    {
        test_integral_contants();
        test_is_void();
        test_remove_const();
        test_remove_volatile();
        test_remove_cv();
        test_add_const();
        test_add_volatile();
        test_add_cv();
        test_remove_reference();
        test_add_reference();
        test_remove_pointer();
        test_add_pointer();
        test_remove_extent();
        test_remove_all_extents();
        test_aligned_storage();
        test_is_integral_base();
        test_is_integral();
        test_is_floating_point_base();
        test_is_floating_point();
        test_is_array();
        test_is_pointer();
        test_is_arithmetic();
        test_is_fundamental();
        test_is_const();
        test_is_reference();
        test_is_function();
        test_is_object();
        test_is_class();
        test_is_union();
        test_is_enum();
        test_is_member_function_pointer();
        test_is_scalar();
        test_is_member_pointer();
        test_is_member_object_pointer();
        test_is_volatile();
        test_is_pod();
        test_is_empty();
        test_is_polymorphic();
        test_is_abstract();
        test_has_trivial_constructor();
        test_has_trivial_copy();
        test_has_trivial_assign();
        test_has_trivial_destructor();
        test_has_nothrow_constructor();
        test_has_nothrow_copy();
        test_has_nothrow_assign();
        test_has_virtual_destructor();
        test_is_signed();
        test_is_unsigned();
        test_alignment_of();
        test_rank();
        test_extent();
        test_is_convertible();
        test_is_base_of();
    }
};
} // namespace TH::KSTD_TEST

Added include/tests/stl_tests/vector_iterator_tests.hpp.




































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#pragma once
#include "tests/test_utils.hpp"
#include "kstd/vector.hpp"

namespace TH::KSTD_TEST
{

extern test_result tr;

class VECTOR_ITERATOR_TEST
{

  public:
	VECTOR_ITERATOR_TEST()
	{
	}
}; // namespace TH::KSTD_TEST
} // namespace TH::KSTD_TEST

Added include/tests/stl_tests/vector_tests.hpp.


























































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
#pragma once
#include "tests/test_utils.hpp"
#include "kstd/vector.hpp"

namespace TH::KSTD_TEST
{

extern test_result tr;

class VECTOR_TEST
{
	struct test_empty_constructor : public kstd::vector<int>
	{
		test_empty_constructor()
		{
			require_correct_preallocation_size();
		}
		void require_correct_preallocation_size()
		{
			tr.assert(this->prealloc_size == 5, "correct size of preallocation");
		}
	};
	struct test_size_on_init
	{
		kstd::vector<int> vector_object;
		test_size_on_init()
		{
			require_empty_vector();
		}
		void require_empty_vector()
		{
			tr.assert(vector_object.size() == 0, "empty vector's size must be 0");
		}
	};
	struct test_push_back_and_size
	{
		int amount;
		kstd::vector<int> vector_object;
		test_push_back_and_size()
		{
			push_back();
			require_correct_size();
		}

		void push_back()
		{
			vector_object.push_back(1);
			vector_object.push_back(2);
			vector_object.push_back(3);
			vector_object.push_back(4);
			vector_object.push_back(5);
			vector_object.push_back(6);
			vector_object.push_back(1);
			vector_object.push_back(2);
			vector_object.push_back(3);
			vector_object.push_back(4);
			vector_object.push_back(5);
			vector_object.push_back(6);
			vector_object.push_back(1);
			vector_object.push_back(2);
			vector_object.push_back(3);
			vector_object.push_back(4);
			vector_object.push_back(5);
			vector_object.push_back(6);
			vector_object.push_back(1);
			vector_object.push_back(2);
			vector_object.push_back(3);
			vector_object.push_back(4);
			vector_object.push_back(5);
			vector_object.push_back(6);
		}

		void require_correct_size()
		{
			tr.assert(vector_object.size() == 24, "Correct Vector Size after Pushbacks");
		}
	};

	struct test_capacity
	{
		kstd::vector<int> test_vector;
		test_capacity()
		{
			tr.assert(test_vector.capacity() == 5, "Correct Capacity");
		}
	};

	struct test_constructor_and_amount_of_elem
	{
		kstd::vector<int> test_vector;
		test_constructor_and_amount_of_elem() : test_vector{10}
		{
			require_correct_vector_size();
		}
		void require_correct_vector_size()
		{
			volatile bool success = true;
			if (test_vector.size() == 10)
			{
				success = false;
			}
			tr.assert(success, "Correct vector size");
		}
	};

	struct test_vector_fill_constructor
	{
		kstd::vector<int> test_vector;
		test_vector_fill_constructor() : test_vector{20, 0xc0ffee}
		{
			require_correct_vector_size();
			require_correct_vector_elements();
		}
		void require_correct_vector_size()
		{
			volatile int size = test_vector.size();
			tr.assert(size == 20, "Correct vector size");
		}
		void require_correct_vector_elements()
		{
			for (const auto &i : test_vector)
			{
				tr.assert(i == 0xc0ffee, "test_vector_fill_constructor");
			}
		}
	};

	struct test_vector_range_constructor
	{
		kstd::vector<int> test_vector1;
		kstd::vector<int> test_vector2;
		test_vector_range_constructor() : test_vector1(10, 0xbada55), test_vector2(test_vector1.begin(), test_vector1.end())
		{
		}

		void require_vectors_correct_size()
		{
			tr.assert(test_vector1.size() == 10, "test_vector_range_constructor - require_vectors_correct_size");
			tr.assert(test_vector1.size() == 10, "test_vector_range_constructor - require_vectors_correct_size");
		}
		void require_vectors_correct_content()
		{
			for (const auto &i : test_vector2)
			{
				tr.assert(i == 0xbada55, "test_vector_range_constructor - require_vectors_correct_content");
			}
		}
	};

	void test_reserve()
	{
		kstd::vector<int> test_vector;
		test_vector.reserve(1000);
		tr.assert(test_vector.capacity() > 1000, "test_vector_reserve");
	}

	void test_vector_iterators()
	{
		kstd::vector<int> test_vector;
		test_vector.push_back(1337);
		test_vector.push_back(628);
		test_vector.push_back(314);
		test_vector.push_back(4);
		test_vector.push_back(3);
		test_vector.push_back(10);
		auto i = test_vector.begin();
		auto j = test_vector.end();
		tr.assert(i != j, "test_vector_iterators");
		tr.assert(*i == test_vector[0], "test_vector_iterators");
		tr.assert(*j == test_vector[6], "test_vector_iterators");
		tr.assert(*++i == test_vector[1], "test_vector_iterators");
		tr.assert(*++j == test_vector[7], "test_vector_iterators");
	}
	void test_vector_const_iterators()
	{
		kstd::vector<int> vec;
		vec.push_back(1337);
		vec.push_back(628);
		vec.push_back(314);
		vec.push_back(4);
		vec.push_back(3);
		vec.push_back(10);
		const kstd::vector<int> test_vector(vec);
		auto k = test_vector.begin();
		auto l = test_vector.end();
		tr.assert(k != l, "test_vector_iterators");
		tr.assert(*k == test_vector[0], "test_vector_iterators");
		tr.assert(*l == test_vector[6], "test_vector_iterators");
		tr.assert(*++k == test_vector[1], "test_vector_iterators");
		tr.assert(*++l == test_vector[7], "test_vector_iterators");
	}
	void test_empty()
	{
		kstd::vector<int> test_vector_empty;
		kstd::vector<int> test_vector_full;

		test_vector_full.push_back(1);
		test_vector_full.push_back(2);
		test_vector_full.push_back(3);
		test_vector_full.push_back(4);

		tr.assert(test_vector_empty.empty() == true, "Test_vector_empty 1");
		tr.assert(test_vector_full.empty() == false, "Test_vector_full 2");
	}

  public:
	VECTOR_TEST()
	{
		test_vector_iterators();
		test_empty_constructor();
		test_size_on_init();
		test_push_back_and_size();
		test_capacity();
		test_constructor_and_amount_of_elem();
		test_vector_fill_constructor();
		test_reserve();
		test_vector_const_iterators();
		test_empty();
	}
}; // namespace TH::KSTD_TEST
} // namespace TH::KSTD_TEST

Added include/tests/test_utils.hpp.














































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#pragma once
#include "buffers/string_view"

namespace TH
{
struct test_result
{
    bool success = true;
    ksdk::string_view comment;
    size_t number_of_fails = 0;
    size_t number_of_subunit_tests = 0;
    void set_comment_from_char_ptr(char *message)
    {
        comment = ksdk::string_view(message, strlen(message));
    }
    void assert(const bool _success, char *message)
    {
        number_of_subunit_tests++;
        if (!_success)
        {
            number_of_fails++;
            success = false;
            set_comment_from_char_ptr(message);
        }
    }
    template <class T, class... U>
    void execute_if_failed(T (*fn)(U...), U... args)
    {
        if (!success)
            fn(args...);
    }
    template <class T, class... U>
    void execute_if_success(T (*fn)(U...), U... args)
    {
        if (success)
            fn(args...);
    }
};
} // namespace TH

Changes to planning/interrupts.xmi.

299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
           <UML:BehavioralFeature.parameter>
            <UML:Parameter kind="return" xmi.id="uPjihbkSQNl8d" type="ujwvUWP0iUnTM"/>
            <UML:Parameter isSpecification="false" name="bit" value="" xmi.id="uBiffmajSeFso" comment="Selects the bit of the features - see enum &#xa;" type="uI56Hn2PdY4eQ" visibility="private"/>
           </UML:BehavioralFeature.parameter>
          </UML:Operation>
         </UML:Classifier.feature>
        </UML:Class>
        <UML:Package isSpecification="false" name="__SYSINF" isAbstract="false" namespace="uz8PHle70dFuD" xmi.id="unZEsm3srHZfM" isRoot="false" isLeaf="false" visibility="public">
         <UML:Namespace.ownedElement>
          <UML:Enumeration isSpecification="false" name="cpu_features" isAbstract="false" namespace="unZEsm3srHZfM" xmi.id="uFofC1U8Rqo0k" comment="i'm too lazy to copy this into it:&#xa;&#xa;enum {&#xa;    CPUID_FEAT_ECX_SSE3         = 1 &lt;&lt; 0, &#xa;    CPUID_FEAT_ECX_PCLMUL       = 1 &lt;&lt; 1,&#xa;    CPUID_FEAT_ECX_DTES64       = 1 &lt;&lt; 2,&#xa;    CPUID_FEAT_ECX_MONITOR      = 1 &lt;&lt; 3,  &#xa;    CPUID_FEAT_ECX_DS_CPL       = 1 &lt;&lt; 4,  &#xa;    CPUID_FEAT_ECX_VMX          = 1 &lt;&lt; 5,  &#xa;    CPUID_FEAT_ECX_SMX          = 1 &lt;&lt; 6,  &#xa;    CPUID_FEAT_ECX_EST          = 1 &lt;&lt; 7,  &#xa;    CPUID_FEAT_ECX_TM2          = 1 &lt;&lt; 8,  &#xa;    CPUID_FEAT_ECX_SSSE3        = 1 &lt;&lt; 9,  &#xa;    CPUID_FEAT_ECX_CID          = 1 &lt;&lt; 10,&#xa;    CPUID_FEAT_ECX_FMA          = 1 &lt;&lt; 12,&#xa;    CPUID_FEAT_ECX_CX16         = 1 &lt;&lt; 13, &#xa;    CPUID_FEAT_ECX_ETPRD        = 1 &lt;&lt; 14, &#xa;    CPUID_FEAT_ECX_PDCM         = 1 &lt;&lt; 15, &#xa;    CPUID_FEAT_ECX_PCIDE        = 1 &lt;&lt; 17, &#xa;    CPUID_FEAT_ECX_DCA          = 1 &lt;&lt; 18, &#xa;    CPUID_FEAT_ECX_SSE4_1       = 1 &lt;&lt; 19, &#xa;    CPUID_FEAT_ECX_SSE4_2       = 1 &lt;&lt; 20, &#xa;    CPUID_FEAT_ECX_x2APIC       = 1 &lt;&lt; 21, &#xa;    CPUID_FEAT_ECX_MOVBE        = 1 &lt;&lt; 22, &#xa;    CPUID_FEAT_ECX_POPCNT       = 1 &lt;&lt; 23, &#xa;    CPUID_FEAT_ECX_AES          = 1 &lt;&lt; 25, &#xa;    CPUID_FEAT_ECX_XSAVE        = 1 &lt;&lt; 26, &#xa;    CPUID_FEAT_ECX_OSXSAVE      = 1 &lt;&lt; 27, &#xa;    CPUID_FEAT_ECX_AVX          = 1 &lt;&lt; 28,&#xa; &#xa;    CPUID_FEAT_EDX_FPU          = 1 &lt;&lt; 0,  &#xa;    CPUID_FEAT_EDX_VME          = 1 &lt;&lt; 1,  &#xa;    CPUID_FEAT_EDX_DE           = 1 &lt;&lt; 2,  &#xa;    CPUID_FEAT_EDX_PSE          = 1 &lt;&lt; 3,  &#xa;    CPUID_FEAT_EDX_TSC          = 1 &lt;&lt; 4,  &#xa;    CPUID_FEAT_EDX_MSR          = 1 &lt;&lt; 5,  &#xa;    CPUID_FEAT_EDX_PAE          = 1 &lt;&lt; 6,  &#xa;    CPUID_FEAT_EDX_MCE          = 1 &lt;&lt; 7,  &#xa;    CPUID_FEAT_EDX_CX8          = 1 &lt;&lt; 8,  &#xa;    CPUID_FEAT_EDX_APIC         = 1 &lt;&lt; 9,  &#xa;    CPUID_FEAT_EDX_SEP          = 1 &lt;&lt; 11, &#xa;    CPUID_FEAT_EDX_MTRR         = 1 &lt;&lt; 12, &#xa;    CPUID_FEAT_EDX_PGE          = 1 &lt;&lt; 13, &#xa;    CPUID_FEAT_EDX_MCA          = 1 &lt;&lt; 14, &#xa;    CPUID_FEAT_EDX_CMOV         = 1 &lt;&lt; 15, &#xa;    CPUID_FEAT_EDX_PAT          = 1 &lt;&lt; 16, &#xa;    CPUID_FEAT_EDX_PSE36        = 1 &lt;&lt; 17, &#xa;    CPUID_FEAT_EDX_PSN          = 1 &lt;&lt; 18, &#xa;    CPUID_FEAT_EDX_CLF          = 1 &lt;&lt; 19, &#xa;    CPUID_FEAT_EDX_DTES         = 1 &lt;&lt; 21, &#xa;    CPUID_FEAT_EDX_ACPI         = 1 &lt;&lt; 22, &#xa;    CPUID_FEAT_EDX_MMX          = 1 &lt;&lt; 23, &#xa;    CPUID_FEAT_EDX_FXSR         = 1 &lt;&lt; 24, &#xa;    CPUID_FEAT_EDX_SSE          = 1 &lt;&lt; 25, &#xa;    CPUID_FEAT_EDX_SSE2         = 1 &lt;&lt; 26, &#xa;    CPUID_FEAT_EDX_SS           = 1 &lt;&lt; 27, &#xa;    CPUID_FEAT_EDX_HTT          = 1 &lt;&lt; 28, &#xa;    CPUID_FEAT_EDX_TM1          = 1 &lt;&lt; 29, &#xa;    CPUID_FEAT_EDX_IA64         = 1 &lt;&lt; 30,&#xa;    CPUID_FEAT_EDX_PBE          = 1 &lt;&lt; 31&#xa;};" isRoot="false" stereotype="enum" isLeaf="false" visibility="public">
           <UML:Enumeration.literal/>
          </UML:Enumeration>
          <UML:Enumeration isSpecification="false" name="cpu_vendor_ids" isAbstract="false" namespace="unZEsm3srHZfM" xmi.id="urWJEgmUWdWr3" isRoot="false" stereotype="enum" isLeaf="false" visibility="public">
           <UML:Enumeration.literal>
            <UML:EnumerationLiteral isSpecification="false" name="CPUID_VENDOR_OLDAMD" value="&quot;AMDisbetter!&quot;" isAbstract="false" namespace="urWJEgmUWdWr3" xmi.id="ubGDzGif6QzZ8" isRoot="false" isLeaf="false" visibility="public"/>






|







299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
           <UML:BehavioralFeature.parameter>
            <UML:Parameter kind="return" xmi.id="uPjihbkSQNl8d" type="ujwvUWP0iUnTM"/>
            <UML:Parameter isSpecification="false" name="bit" value="" xmi.id="uBiffmajSeFso" comment="Selects the bit of the features - see enum &#xa;" type="uI56Hn2PdY4eQ" visibility="private"/>
           </UML:BehavioralFeature.parameter>
          </UML:Operation>
         </UML:Classifier.feature>
        </UML:Class>
        <UML:Package isSpecification="false" name="SYSINF" isAbstract="false" namespace="uz8PHle70dFuD" xmi.id="unZEsm3srHZfM" isRoot="false" isLeaf="false" visibility="public">
         <UML:Namespace.ownedElement>
          <UML:Enumeration isSpecification="false" name="cpu_features" isAbstract="false" namespace="unZEsm3srHZfM" xmi.id="uFofC1U8Rqo0k" comment="i'm too lazy to copy this into it:&#xa;&#xa;enum {&#xa;    CPUID_FEAT_ECX_SSE3         = 1 &lt;&lt; 0, &#xa;    CPUID_FEAT_ECX_PCLMUL       = 1 &lt;&lt; 1,&#xa;    CPUID_FEAT_ECX_DTES64       = 1 &lt;&lt; 2,&#xa;    CPUID_FEAT_ECX_MONITOR      = 1 &lt;&lt; 3,  &#xa;    CPUID_FEAT_ECX_DS_CPL       = 1 &lt;&lt; 4,  &#xa;    CPUID_FEAT_ECX_VMX          = 1 &lt;&lt; 5,  &#xa;    CPUID_FEAT_ECX_SMX          = 1 &lt;&lt; 6,  &#xa;    CPUID_FEAT_ECX_EST          = 1 &lt;&lt; 7,  &#xa;    CPUID_FEAT_ECX_TM2          = 1 &lt;&lt; 8,  &#xa;    CPUID_FEAT_ECX_SSSE3        = 1 &lt;&lt; 9,  &#xa;    CPUID_FEAT_ECX_CID          = 1 &lt;&lt; 10,&#xa;    CPUID_FEAT_ECX_FMA          = 1 &lt;&lt; 12,&#xa;    CPUID_FEAT_ECX_CX16         = 1 &lt;&lt; 13, &#xa;    CPUID_FEAT_ECX_ETPRD        = 1 &lt;&lt; 14, &#xa;    CPUID_FEAT_ECX_PDCM         = 1 &lt;&lt; 15, &#xa;    CPUID_FEAT_ECX_PCIDE        = 1 &lt;&lt; 17, &#xa;    CPUID_FEAT_ECX_DCA          = 1 &lt;&lt; 18, &#xa;    CPUID_FEAT_ECX_SSE4_1       = 1 &lt;&lt; 19, &#xa;    CPUID_FEAT_ECX_SSE4_2       = 1 &lt;&lt; 20, &#xa;    CPUID_FEAT_ECX_x2APIC       = 1 &lt;&lt; 21, &#xa;    CPUID_FEAT_ECX_MOVBE        = 1 &lt;&lt; 22, &#xa;    CPUID_FEAT_ECX_POPCNT       = 1 &lt;&lt; 23, &#xa;    CPUID_FEAT_ECX_AES          = 1 &lt;&lt; 25, &#xa;    CPUID_FEAT_ECX_XSAVE        = 1 &lt;&lt; 26, &#xa;    CPUID_FEAT_ECX_OSXSAVE      = 1 &lt;&lt; 27, &#xa;    CPUID_FEAT_ECX_AVX          = 1 &lt;&lt; 28,&#xa; &#xa;    CPUID_FEAT_EDX_FPU          = 1 &lt;&lt; 0,  &#xa;    CPUID_FEAT_EDX_VME          = 1 &lt;&lt; 1,  &#xa;    CPUID_FEAT_EDX_DE           = 1 &lt;&lt; 2,  &#xa;    CPUID_FEAT_EDX_PSE          = 1 &lt;&lt; 3,  &#xa;    CPUID_FEAT_EDX_TSC          = 1 &lt;&lt; 4,  &#xa;    CPUID_FEAT_EDX_MSR          = 1 &lt;&lt; 5,  &#xa;    CPUID_FEAT_EDX_PAE          = 1 &lt;&lt; 6,  &#xa;    CPUID_FEAT_EDX_MCE          = 1 &lt;&lt; 7,  &#xa;    CPUID_FEAT_EDX_CX8          = 1 &lt;&lt; 8,  &#xa;    CPUID_FEAT_EDX_APIC         = 1 &lt;&lt; 9,  &#xa;    CPUID_FEAT_EDX_SEP          = 1 &lt;&lt; 11, &#xa;    CPUID_FEAT_EDX_MTRR         = 1 &lt;&lt; 12, &#xa;    CPUID_FEAT_EDX_PGE          = 1 &lt;&lt; 13, &#xa;    CPUID_FEAT_EDX_MCA          = 1 &lt;&lt; 14, &#xa;    CPUID_FEAT_EDX_CMOV         = 1 &lt;&lt; 15, &#xa;    CPUID_FEAT_EDX_PAT          = 1 &lt;&lt; 16, &#xa;    CPUID_FEAT_EDX_PSE36        = 1 &lt;&lt; 17, &#xa;    CPUID_FEAT_EDX_PSN          = 1 &lt;&lt; 18, &#xa;    CPUID_FEAT_EDX_CLF          = 1 &lt;&lt; 19, &#xa;    CPUID_FEAT_EDX_DTES         = 1 &lt;&lt; 21, &#xa;    CPUID_FEAT_EDX_ACPI         = 1 &lt;&lt; 22, &#xa;    CPUID_FEAT_EDX_MMX          = 1 &lt;&lt; 23, &#xa;    CPUID_FEAT_EDX_FXSR         = 1 &lt;&lt; 24, &#xa;    CPUID_FEAT_EDX_SSE          = 1 &lt;&lt; 25, &#xa;    CPUID_FEAT_EDX_SSE2         = 1 &lt;&lt; 26, &#xa;    CPUID_FEAT_EDX_SS           = 1 &lt;&lt; 27, &#xa;    CPUID_FEAT_EDX_HTT          = 1 &lt;&lt; 28, &#xa;    CPUID_FEAT_EDX_TM1          = 1 &lt;&lt; 29, &#xa;    CPUID_FEAT_EDX_IA64         = 1 &lt;&lt; 30,&#xa;    CPUID_FEAT_EDX_PBE          = 1 &lt;&lt; 31&#xa;};" isRoot="false" stereotype="enum" isLeaf="false" visibility="public">
           <UML:Enumeration.literal/>
          </UML:Enumeration>
          <UML:Enumeration isSpecification="false" name="cpu_vendor_ids" isAbstract="false" namespace="unZEsm3srHZfM" xmi.id="urWJEgmUWdWr3" isRoot="false" stereotype="enum" isLeaf="false" visibility="public">
           <UML:Enumeration.literal>
            <UML:EnumerationLiteral isSpecification="false" name="CPUID_VENDOR_OLDAMD" value="&quot;AMDisbetter!&quot;" isAbstract="false" namespace="urWJEgmUWdWr3" xmi.id="ubGDzGif6QzZ8" isRoot="false" isLeaf="false" visibility="public"/>

Changes to src/acpi/acpi_access.cpp.

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
#include "acpi/acpi_access.h"
#include "bios/BDA.hpp"
#include "asm_shims/shims.h"

namespace ACPI
{

   acpi_interface::acpi_interface()
   {
       if (sdt_wrap.fadt != nullptr)
       {
           active = true;
       }
       aml_interpreter.parse(sdt_wrap.get_dsdt()->getCode());
   }

   void acpi_interface::stop_acpi()
   {
       sdt_wrap.fadt->disable_acpi();
   }

   void acpi_interface::start_acpi()
   {
       sdt_wrap.fadt->enable_acpi();
   }

} // namespace ACPI





>
|
|
|
|
|
|
|
|

|
|
|
|

|
|
|
|


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
#include "acpi/acpi_access.h"
#include "bios/BDA.hpp"
#include "asm_shims/shims.h"

namespace ACPI
{

acpi_interface::acpi_interface()
{
    if (sdt_wrap.fadt.stored != nullptr)
    {
        active = true;
    }
    aml_interpreter.parse(sdt_wrap.dsdt.getCode());
}

void acpi_interface::stop_acpi()
{
    sdt_wrap.fadt.disable_acpi();
}

void acpi_interface::start_acpi()
{
    sdt_wrap.fadt.enable_acpi();
}

} // namespace ACPI

Changes to src/acpi/aml_interpreter.cpp.

88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
}

void interpreter::parse_term_list()
{
    //TermList := Nothing | <TermObj TermList>
    if (code_offset == code.size())
    {
        Termutils::cout << "nothing\n";
        return;
    }
    else
    {
        switch (code[code_offset])
        {
        case int(name_space_modifier_object_constants::def_alias):
        {
            Termutils::cout << "defalias\n";
            parse_def_alias();
            parse_term_list();
            break;
        }
        case int(name_space_modifier_object_constants::def_name): //NamespaceModifier, DefName
        {
            Termutils::cout << "defname\n";
            //parse_def_name();
            break;
        }
        case int(name_space_modifier_object_constants::def_scope): //NamespaceModifier, DefScope
        {
            Termutils::cout << "defscope\n";
            break;
        }
        default:
        {
            Termutils::cout << code[code_offset] << "\n";
            Termutils::cout << ":'(\n";
            break;
        }
        }
    }
}

void interpreter::parse_aml_code()






<








<






<





<




<
<







88
89
90
91
92
93
94

95
96
97
98
99
100
101
102

103
104
105
106
107
108

109
110
111
112
113

114
115
116
117


118
119
120
121
122
123
124
}

void interpreter::parse_term_list()
{
    //TermList := Nothing | <TermObj TermList>
    if (code_offset == code.size())
    {

        return;
    }
    else
    {
        switch (code[code_offset])
        {
        case int(name_space_modifier_object_constants::def_alias):
        {

            parse_def_alias();
            parse_term_list();
            break;
        }
        case int(name_space_modifier_object_constants::def_name): //NamespaceModifier, DefName
        {

            //parse_def_name();
            break;
        }
        case int(name_space_modifier_object_constants::def_scope): //NamespaceModifier, DefScope
        {

            break;
        }
        default:
        {


            break;
        }
        }
    }
}

void interpreter::parse_aml_code()

Changes to src/acpi/wrappers.cpp.

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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110

111
112
113
114
115
116
117
118
119
120
121
122
123
124

125
126
127
128
129
130



131
132

133
134

135
136
137
138

139
140
141
142
143
144


145
146
147

148
149
150
151
152
153





154
155
156
157
158
159
160
161
162
163
164
165
166

167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187

188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235


236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
#include "acpi/wrappers.h"
#include "memory/lma_allocator.h"


namespace ACPI
{

///////////////////////////////////////////////////////////////

madt_wrapper::madt_wrapper(SDT::MADT *ptr)
{
    madt_ptr = ptr;
    Termutils::cout << "highest val : " << (madt_ptr->h.Length - sizeof(SDT::generic_sdt)) << "\n";
}


bool madt_wrapper::is_out_of_bounds(size_t _offset)
{
    return _offset > (madt_ptr->h.Length - sizeof(SDT::generic_sdt));
}





SDT::GENERIC_MADT_ENTRY *madt_wrapper::get_next_entry()
{
    offset += sizeof(SDT::GENERIC_MADT_ENTRY *);
    if (is_out_of_bounds(offset))
        offset = 0; //loop back around

    return (SDT::GENERIC_MADT_ENTRY *)(&madt_ptr->Entries[offset]);
}

SDT::GENERIC_MADT_ENTRY *madt_wrapper::get_next_entry_if()
{ //only if there is a next entry, else return NULL
    size_t add = 1;
    offset += add;
    if (is_out_of_bounds(offset))
    {
        offset -= add;

        return nullptr;
    }
    return (SDT::GENERIC_MADT_ENTRY *)(&madt_ptr->Entries[offset]);
}

SDT::GENERIC_MADT_ENTRY *madt_wrapper::get_entry(size_t index)
{
    SDT::GENERIC_MADT_ENTRY *tmp;
    size_t offset_store = offset;
    offset = 0;
    if (is_out_of_bounds(index))
    {
        tmp = nullptr;
    }
    for (; offset <= index;)
    {
        tmp = get_next_entry();
    }
    offset = offset_store;
    return tmp;
}

SDT::GENERIC_MADT_ENTRY *madt_wrapper::get_first_entry_with(uint8_t type)
{
    if (type > 12)
    {
        return nullptr;
    }
    offset = 0;
    for (; !is_out_of_bounds(offset);)
    {
        SDT::GENERIC_MADT_ENTRY *current_table = (SDT::GENERIC_MADT_ENTRY *)madt_ptr->Entries[offset];
        offset += current_table->RecordLength;
        if (current_table->EntryType == type)
        {
            return current_table;
        }
    }
    return nullptr;
}

void madt_wrapper::reset_entry_pointer()
{
    offset = 0;
}

///////////////////////////////
///////////////////////////////

sdt_wrapper::sdt_wrapper()
{
    auto check = [](sign_8_type *ptr) -> bool {
        struct SDT::RSDP *rsdp_ptr = (SDT::RSDP *)ptr;
        uint8_t *bptr;
        uint8_t check = 0;
        constexpr char *sig = "RSD PTR ";

        if (memcmp(ptr, sig, 8) == 0)
        {
            bptr = (uint8_t *)ptr;
            for (int i = 0; i < sizeof(struct SDT::RSDP); i++)
            {
                check += *bptr;
                bptr++;
            }
            return check == 0;
        }
        return false;
    };

    auto set_rsdp = [this](void *ptr) {
        SDT::RSDP *rsdpptr = (SDT::RSDP *)ptr;
        acpi_version = rsdpptr->Revision;
        if (rsdpptr->Revision == 0)
        { //only one table to be used

            rsdp_20_ptr = NULL;
            rsdp_ptr = rsdpptr;
        }
        else
        {
            rsdp_20_ptr = (SDT::RSDP20 *)ptr;
            rsdp_ptr = rsdpptr;
        }
    };

    bool found_rsdp = false;

    ksdk::buffer<sign_8_type> search_buf{(sign_8_type *)0x000E0000, (sign_8_type *)0x00100000};
    for (auto it = search_buf.begin(); it != search_buf.end(); it++)

    {
        if (check(&*it))
        {
            set_rsdp(&*it);
            found_rsdp = true;
            break;



        }
    }


    ksdk::buffer<sign_8_type> ebda_search_buf{(sign_8_type *)((short *)0x40E), (sign_8_type *)(((short *)0x40E) + 1025)};


    if (found_rsdp)
    {
        for (auto it = ebda_search_buf.begin(); it != ebda_search_buf.end(); it++)

        {
            if (check(&*it))
            {
                set_rsdp(&*it);
                found_rsdp = true;
                break;


            }
        }
    }


    if (!found_rsdp)
    {
        return; //no rsdp found, there's no need in setting up other variables
    }
    // set the different things





    number_tables = 0;
    rsdt_ptr = (SDT::RSDT *)rsdp_ptr->RsdtAddress;
    if (acpi_version > 1)
        [[likely]] {
            number_tables = (xsdt_ptr->h.Length - sizeof(SDT::generic_sdt)) / 8;
            xsdt_ptr = (SDT::XSDT *)rsdp_20_ptr->XsdtAddress;
        } else
            [[unlikely]] {
                number_tables = (rsdt_ptr->h.Length - sizeof(SDT::generic_sdt)) / 4;
            } Termutils::cout
            << number_tables << " number of tables\n";
    find_structures();
} // namespace ACPI


SDT::generic_sdt *sdt_wrapper::get_table(size_t index)
{
    if (index >= number_tables)
    { //no such index
        return NULL;
    }

#pragma message "@QNeko : find a way to optimize this out"
    if (acpi_version == 0)
        [[unlikely]] {
            return (SDT::generic_sdt *)(rsdt_ptr->PointerToOtherSDT[index]);
        } else
            [[likely]] {
                return (SDT::generic_sdt *)(xsdt_ptr->PointerToOtherSDT[index]);
            }
}

void sdt_wrapper::find_structures()
{


    SDT::generic_sdt *fadt_tmp = get_table(0); //first table is a fadt by standard
    fadt = new fadt_wrapper((SDT::FADT *)fadt_tmp);

    /*facs = (SDT::FACS *)fadt->X_FirmwareControl;*/

    for (size_t i = 0; ft.all_found() != true; i++)
    {
        SDT::generic_sdt *a = get_table(i);
        if (memcmp(a->Signature, "APIC", 4) == 0)
        {
            madt = new (USE_LMA) madt_wrapper((SDT::MADT *)a);
            ft.APIC = true;
        }
    }
}

dsdt_wrapper *sdt_wrapper::get_dsdt()
{
    return new (USE_LMA) dsdt_wrapper((SDT::DSDT *)fadt->stored->Dsdt);
}

///////////////////////////////////////////////
///////////////////////////////////////////////
dsdt_wrapper::dsdt_wrapper(SDT::DSDT *other)
{
    stored = other;
}

ksdk::string_view dsdt_wrapper::getCode()
{
    size_t length = stored->h.Length - sizeof(SDT::generic_sdt);
    char *start = (char *)stored->DefinitionBlock;
    return ksdk::string_view(start, length);
}

///////////////////////////////////////////////
///////////////////////////////////////////////

fadt_wrapper::fadt_wrapper(SDT::FADT *ptr)
{
    stored = ptr;
    *&(stored->Reserved) = 0;
}

SDT::DSDT *fadt_wrapper::get_dsdt()
{
    return (SDT::DSDT *)stored->Dsdt;
}



void fadt_wrapper::enable_acpi()
{
    outb(stored->SMI_CommandPort, stored->AcpiEnable);
    while (inw(stored->PM1aControlBlock) & 1 == 0)
    {
    }
}

void fadt_wrapper::disable_acpi()
{
    outb(stored->SMI_CommandPort, stored->AcpiDisable);
}

} // namespace ACPI

>




<
<
|
<
<
<
<
<
>




>
>
>
>



<

|
>
|
<
<
<
<
<
<
<
<
<
<
<
<
<








<

<

<

<







<

<



|
|
|
<
|
<




|
|
<
<
<
<
<
<
|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
<
>
|
|
|
|
|
|
|
|
<
|
<

<
<
>
|
<
<
<
<
<
>
>
>
|
|
>
|
<
>
|
<
|
<
>
|
<
<
<
<
<
>
>
|
|
<
>
|
<
<
<
<
<
>
>
>
>
>
|
|
<
<
<
|
<
<
<
<
<

<
>



|
|
|
|
|
|
|
|
|
|
|
|
|




<
>
|
<
<
<
<
|




|





|
<
<
<
<
<
<
|
<
<
<




|



<
<
<
|

<



|

<

>
>




|
<
<








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
76
77
78
79
80
81

82
83

84

85
86





87
88
89
90

91
92





93
94
95
96
97
98
99



100





101

102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122

123
124




125
126
127
128
129
130
131
132
133
134
135
136






137



138
139
140
141
142
143
144
145



146
147

148
149
150
151
152

153
154
155
156
157
158
159
160


161
162
163
164
165
166
167
168
#include "acpi/wrappers.h"
#include "memory/lma_allocator.h"
#include "misc/kernel_panic.h"

namespace ACPI
{



madt_wrapper::madt_wrapper(SDT::MADT *ptr) : madt_ptr(ptr) {}





madt_wrapper::madt_wrapper() {}
bool madt_wrapper::is_out_of_bounds(size_t _offset)
{
    return _offset > (madt_ptr->h.Length - sizeof(SDT::generic_sdt));
}

SDT::GENERIC_MADT_ENTRY *madt_wrapper::get_current_entry(){
    return reinterpret_cast<SDT::GENERIC_MADT_ENTRY *>(&madt_ptr->Entries[offset]);
}

SDT::GENERIC_MADT_ENTRY *madt_wrapper::get_next_entry()
{

    if (is_out_of_bounds(offset))
        offset = 0;
    offset += get_current_entry()->RecordLength;
    return get_current_entry();













}

SDT::GENERIC_MADT_ENTRY *madt_wrapper::get_entry(size_t index)
{
    SDT::GENERIC_MADT_ENTRY *tmp;
    size_t offset_store = offset;
    offset = 0;
    if (is_out_of_bounds(index))

        tmp = nullptr;

    for (; offset <= index;)

        tmp = get_next_entry();

    offset = offset_store;
    return tmp;
}

SDT::GENERIC_MADT_ENTRY *madt_wrapper::get_first_entry_with(uint8_t type)
{
    if (type > 12)

        return nullptr;

    offset = 0;
    for (; !is_out_of_bounds(offset);)
    {
      SDT::GENERIC_MADT_ENTRY *current_table = get_current_entry();
      offset += current_table->RecordLength;
      if (current_table->EntryType == type)

        return current_table;

    }
    return nullptr;
}

void madt_wrapper::reset_entry_pointer() { offset = 0; }







inline void sdt_wrapper::set_rsdp(void *ptr)
{




















    SDT::RSDP *rsdpptr = reinterpret_cast<SDT::RSDP *>(ptr);
    acpi_version = rsdpptr->Revision;
    if (UTILS::is_rsdp_v2(rsdpptr->Revision))

    {
        rsdp_20_ptr = reinterpret_cast<SDT::RSDP20 *>(ptr);
        rsdp_ptr = rsdpptr;
    }
    else
    {
        rsdp_20_ptr = NULL;
        rsdp_ptr = rsdpptr;
    }

}




int sdt_wrapper::get_number_of_tables()
{





    if (acpi_version > 1)
        return (xsdt_ptr->h.Length - sizeof(SDT::generic_sdt) - 1) / 8;
    return (rsdt_ptr->h.Length - sizeof(SDT::generic_sdt) - 1) / 4;
}

void sdt_wrapper::set_rsdt(uint32_t physical_position)
{

    rsdt_ptr = reinterpret_cast<SDT::RSDT *>(physical_position);
}



void sdt_wrapper::set_xsdt(uint32_t ptr)
{





    if (acpi_version > 1)
        xsdt_ptr = reinterpret_cast<SDT::XSDT *>(ptr);
}


sdt_wrapper::sdt_wrapper()
{





    rsdp_ptr = UTILS::find_rsdp();
    if (rsdp_ptr == nullptr)
        Exception::kernel_panic("ACPI: no rsdp found, initialization of ACPI not "
                                "possible. Please run CLINL on a device that "
                                "supports ACPI!");
    number_tables = get_number_of_tables();
    set_rsdt(rsdp_ptr->RsdtAddress);



    set_xsdt(rsdp_20_ptr->XsdtAddress);





    find_structures();

}

SDT::generic_sdt *sdt_wrapper::get_table(size_t index)
{
    if (acpi_version != 0)
        return reinterpret_cast<SDT::generic_sdt *>(xsdt_ptr->PointerToOtherSDT[index]);
    return reinterpret_cast<SDT::generic_sdt *>(rsdt_ptr->PointerToOtherSDT[index]);
}

void sdt_wrapper::set_fadt()
{
    fadt = fadt_wrapper(reinterpret_cast<SDT::FADT *>(get_table(0)));
}

void sdt_wrapper::set_dsdt() 
{
    dsdt = dsdt_wrapper (reinterpret_cast<SDT::DSDT*> (fadt.stored->Dsdt));
}

void sdt_wrapper::find_structures()
{

    set_fadt();
    set_dsdt();




    for (size_t i = 0; ft.all_found(); ++i)
    {
        SDT::generic_sdt *a = get_table(i);
        if (memcmp(a->Signature, "APIC", 4) == 0)
        {
            madt = madt_wrapper(reinterpret_cast<SDT::MADT *>(a));
            ft.APIC = true;
        }
    }
}

dsdt_wrapper::dsdt_wrapper(SDT::DSDT *other) { stored = other; }






dsdt_wrapper::dsdt_wrapper() { stored = nullptr; }




ksdk::string_view dsdt_wrapper::getCode()
{
    size_t length = stored->h.Length - sizeof(SDT::generic_sdt);
    char *start = reinterpret_cast<char *> (stored->DefinitionBlock);
    return ksdk::string_view(start, length);
}




fadt_wrapper::fadt_wrapper(SDT::FADT *ptr) : stored(ptr)
{

    *&(stored->Reserved) = 0;
}

fadt_wrapper::fadt_wrapper() : stored(nullptr)
{

}

SDT::DSDT *fadt_wrapper::get_dsdt() { return reinterpret_cast<SDT::DSDT *> (stored->Dsdt); }

void fadt_wrapper::enable_acpi()
{
    outb(stored->SMI_CommandPort, stored->AcpiEnable);
    while (inw(stored->PM1aControlBlock) & 1 == 0);


}

void fadt_wrapper::disable_acpi()
{
    outb(stored->SMI_CommandPort, stored->AcpiDisable);
}

} // namespace ACPI

Changes to src/buffers/vga_buffer.cpp.

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
#include "buffers/vga_buffer.h"
#include "bios/BDA.hpp"




ksdk::buffer<char> VGA::buffer;
ksdk::buffer<VGA::character> VGA::text_buffer;


size_t VGA::TEXT_WIDTH;
size_t VGA::TEXT_HEIGHT;
size_t VGA::text_cursor;
VGA::color_mode VGA::text_color;

void VGA::initialize()
{
	TEXT_WIDTH = BIOS::BDA.get_text_mode_cols();
	TEXT_HEIGHT = BIOS::BDA.get_text_mode_rows();
	text_cursor = 0;


	VGA::buffer = ksdk::buffer<char>((char *)0x000A0000, (char *)0x000BFFFF);





	VGA::text_buffer = ksdk::buffer<VGA::character>(
		(VGA::character *)0x000B8000,
		TEXT_WIDTH * TEXT_HEIGHT);

	text_color = make_color_mode(color::WHITE);

	for (VGA::character &c : VGA::text_buffer)

	{
		c = VGA::character(' ', text_color);



	}
}








__internals::check<sizeof(VGA::character) * 8 == 16> a;

>

>
>
|
<
>

|
|
|
|

|




>
|
<
>
>
>
>
>
|
<
|
|
<

<
>
|
<
>
>
>
|
|
>
|
>
>
>
>
>
>
|
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
#include "buffers/vga_buffer.h"
#include "bios/BDA.hpp"
#include "kstd/type_traits.hpp"

namespace VGA
{
ksdk::buffer<char> buffer;

ksdk::buffer<character> text_buffer;

size_t TEXT_WIDTH;
size_t TEXT_HEIGHT;
size_t text_cursor;
color_mode text_color;

void initialize_variables()
{
	TEXT_WIDTH = BIOS::BDA.get_text_mode_cols();
	TEXT_HEIGHT = BIOS::BDA.get_text_mode_rows();
	text_cursor = 0;
	text_color = make_color_mode(color::WHITE);
}


void initialize_buffers()
{

	buffer = ksdk::buffer<char>(reinterpret_cast<char *>(0x000A0000), reinterpret_cast<char *>(0x000BFFFF));
	text_buffer = ksdk::buffer<character>(reinterpret_cast<character *>(0x000B8000),

										  TEXT_WIDTH * TEXT_HEIGHT);
}



void initialize()
{

	initialize_variables();
	initialize_buffers();
	empty_vga_buffer();
}

void empty_vga_buffer()
{
	text_cursor = 0;
	for (size_t i = 0; i < buffer.size(); i++, buffer[i] = 0)
		;
}
} // namespace VGA

kstd::enable_if<sizeof(VGA::character) * 8 == 16, int> a;

Changes to src/init.cpp.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include "misc/includes.h"

namespace TH
{
extern void TESTS_REGISTER();
}

extern "C"
{
	void kernel_main(multiboot_info_t *mboot, uint32_t magic)
	{
		INIT::initialize(mboot, magic);
		Termutils::cout << Termutils::terminal_output::int_mode::hex;
		INIT::display_greeting();
		INIT::display_mem_info(Paging::Physical::physical_memory);

		TH::TESTS_REGISTER();
	}
}



|











|


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include "misc/includes.h"

namespace TH
{
extern void RUN_TESTS();
}

extern "C"
{
	void kernel_main(multiboot_info_t *mboot, uint32_t magic)
	{
		INIT::initialize(mboot, magic);
		Termutils::cout << Termutils::terminal_output::int_mode::hex;
		INIT::display_greeting();
		INIT::display_mem_info(Paging::Physical::physical_memory);

		TH::RUN_TESTS();
	}
}

Changes to src/interrupts/pic_wrapper.cpp.

1
2
3
4
5
6
7
8































9













#include "interrupts/pic_wrapper.h"

namespace INT
{

namespace __PICS
{
}































} // namespace INT

















|

|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
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
#include "interrupts/pic_wrapper.h"

namespace INT
{

namespace PICS
{

PIC_8259::PIC_8259(bool _type, int offset)
{
    type = _type; // true ^= master, false ^= slave
    uint8_t ICW4_BUF;
    uint8_t ident;
    if (type)
    {
        ports.command = 0x0020;
        ports.data = 0x0021;
        ICW4_BUF = 0x0C;
        ident = 4;
    }
    else
    {
        ports.command = 0x00A0;
        ports.data = 0x00A1;
        ICW4_BUF = 0x08;
        ident = 2;
    }
    uint8_t mask = inb(ports.data);

    outb(ports.command, 0x10 + ICW4_BUF);
    io_wait();
    outb(ports.data, offset);
    io_wait();
    outb(ports.data, ident);
    io_wait();
    outb(ports.data, 0x01);
    io_wait();

    outb(ports.data, mask); //restore the mask
} // namespace INT

void PIC_8259::disable()
{
    outb(ports.command, 0xFF);
}

} // namespace PICS

pic_wrapper::pic_wrapper(int vec1, int vec2)
{
    //pics = kstd::make_pair<PICS::PIC_8259, PICS::PIC_8259>(PICS::PIC_8259(true, vec1), PICS::PIC_8259(false, vec2));
}
} // namespace INT

Changes to src/libk/mem_alloc.cpp.

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
#include "libk/memory.h"
#include "memory/page_directory.h"
#include "libk/string.h"




void *operator new(size_t size)
{
	void *p;
	while (p == 0)
	{ //in case malloc fails
		p = malloc(size);
	}

	return p;
}

void operator delete(void *ptr, size_t size)
{
	free(ptr);
}

extern "C"
{

	struct no_paging_t
	{
	} no_paging;

	void *malloc(size_t sz)
	{
		return Paging::Physical::memory->malloc(sz);
	}

	void *realloc(void *old_ptr, size_t sz)
	{


>
>
>




|
<

<
>










<
<
<
<
<







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
#include "libk/memory.h"
#include "memory/page_directory.h"
#include "libk/string.h"
#include "kstd/vector.hpp"
#include "kstd/ext/rangeit.hpp"
#include "termutils/terminal.h"

void *operator new(size_t size)
{
	void *p;
	do {

		p = malloc(size);

	} while (p == nullptr);
	return p;
}

void operator delete(void *ptr, size_t size)
{
	free(ptr);
}

extern "C"
{





	void *malloc(size_t sz)
	{
		return Paging::Physical::memory->malloc(sz);
	}

	void *realloc(void *old_ptr, size_t sz)
	{

Changes to src/libk/mem_funcs.cpp.

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
76
77
#include "libk/string.h"
#include "algorithms/copy.hpp"
#include "buffers/buffer.hpp"

extern "C"{


	int memcmp(const void* lhs, const void* rhs, size_t len)
	{
		auto lit = (char*)lhs;
		auto rit = (char*)rhs;
		for(size_t idx=0;idx<len;++idx)

		{
			if(*lit>*rit)

				return 1;
			else if(*lit<*rit)
				return -1;


		}
		return 0;
	}

	void* memcpy(void* dest, const void* src, size_t len)
	{
		auto begin=(char*)src;
		auto end=begin+len;
		copy(begin,end,(char*)dest);



















		return dest;
	}

	
	void* memmove(void* dest, const void* src, size_t len)
	{
		ksdk::buffer<char> source((char*)src,len);
		if (dest < src) {
			copy(
				source.begin(),
				source.end(),
				(char*)dest
			);
		} else {
			copy(
				source.rbegin(),
				source.rend(),
				__internals::r_op_iterator<char>((char*)dest)
			);
		}
		return dest;
	}
	
	void* memset(void* dest, int v, size_t len)
	{
		auto begin = (char*)dest;
		auto end=begin+len;
		for(auto it=begin;it!=end;++it)
			*it=v;
		return dest;
	}
	
	size_t strlen(const char* s)
	{
		size_t len=0;
		while(s[len])len++;
		return len;
	}

	bool strcompare (const char* a, const char* b) {
		size_t size = strlen(a);
		if (size != strlen(b)) {
			return false;
		}
		for (size_t offset = 0; offset < size; offset++) {
			if (a[offset] != b[offset]) {
				return false;
			}
		}
		return true;
	}
}



|
|
>
|

|
|
<
>

<
>

|

>
>




|

|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|

|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
|


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
#include "libk/string.h"
#include "algorithms/copy.hpp"
#include "buffers/buffer.hpp"

extern "C"
{

	int memcmp(const void *lhs, const void *rhs, size_t len)
	{
		auto lit = (char *)lhs;
		auto rit = (char *)rhs;

		for (size_t idx = 0; idx < len; ++idx)
		{

			if (*lit > *rit)
				return 1;
			else if (*lit < *rit)
				return -1;
			lit++;
			rit++;
		}
		return 0;
	}

	void *memcpy(void *dest, const void *src, size_t len)
	{
		auto begin = (char *)src;
		auto end = begin + len;
		copy(begin, end, (char *)dest);
		return dest;
	}

	void *memmove(void *dest, const void *src, size_t len)
	{
		ksdk::buffer<char> source((char *)src, len);
		if (dest < src)
			copy(source.begin(), source.end(), (char *)dest);
		else
			copy(source.rbegin(), source.rend(), internals::r_op_iterator<char>((char *)dest));
		return dest;
	}

	void *memset(void *dest, int v, size_t len)
	{
		auto begin = (char *)dest;
		auto end = begin + len;
		for (auto it = begin; it != end; ++it)
			*it = v;
		return dest;
	}






























	size_t strlen(const char *s)
	{
		size_t len = 0;
		while (s[len])
			len++;












		return len;
	}
}

Changes to src/memory/paging_init.cpp.

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

#include "memory/page_directory.h"
#include "memory/physical_memory.h"
#include "termutils/terminal.h"

Paging::page_directory *page_dir;



Paging::Physical::physical_layout *Paging::Physical::memory;
uint64_t Paging::Physical::physical_memory;


uint64_t Paging::initialize(multiboot_memory_map_t *mmap, size_t len)

{
	multiboot_memory_map32_t *map = (multiboot_memory_map32_t *)mmap;
	Physical::memory = new ((void *)0x01000000) Physical::physical_layout(
		(char *)(0x01000000 + (1 << 12)),
		4 << 20);
	uint32_t mem_beg = 0x01000000 + (1 << 12) + (4 << 20);
	uint32_t bcnt = 0;
	for (uint32_t i = 0; i < len; i++)
	{
		if (map[i].type == 1)

		{
			if (map[i].base_addr_low % (4 << 10))
			{
				map[i].length_low -= (map[i].base_addr_low % (4 << 10));

				map[i].base_addr_low = map[i].base_addr_low - (map[i].base_addr_low % (4 << 10)) + (4 << 10);
			}

			if (map[i].base_addr_low >= mem_beg)
			{
				auto before_last_b = map[i].base_addr_low + map[i].length_low - (1 << 16);
				for (auto it = map[i].base_addr_low; it <= before_last_b; it += 1 << 16)
				{
					Physical::memory->add_block((char *)it);
					bcnt++;
				}
			}
			else if (map[i].base_addr_low + map[i].length_low >= mem_beg)
			{
				auto before_last_b = map[i].base_addr_low + map[i].length_low - (1 << 16);
				for (auto it = mem_beg; it <= before_last_b; it += 1 << 16)
				{
					Physical::memory->add_block((char *)it);
					bcnt++;

				}
			}
		}
	}









	Physical::physical_memory = bcnt << 16;

	page_dir = new (Physical::memory->malloc(sizeof(page_dir))) page_directory();

	return Physical::physical_memory;
}




|
>
>
>
|
|
>

<
>
|
<
<
<
<
|
|
<
|
<
>
|
|
|
|
>
|
|
>
|
|
<
|
|
|
|
|
|
|
|
<
|
<
|
<
>
|
|
|
|
>
>
>
>
>
>
>
>
>
|





>
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
#include "memory/page_directory.h"
#include "memory/physical_memory.h"
#include "termutils/terminal.h"

namespace Paging
{
namespace Physical
{
physical_layout *memory;
uint64_t physical_memory;
} // namespace Physical


page_directory *page_dir;





const uint32_t mem_beg = 0x01000000 + (1 << 12) + (4 << 20);
uint32_t block_count = 0;



inline void handle_usable_memory_block(auto &memory_block)
{
	if (memory_block.base_addr_low % (4 << 10))
	{
		memory_block.length_low -= (memory_block.base_addr_low % (4 << 10));
		memory_block.base_addr_low = memory_block.base_addr_low -
							   (memory_block.base_addr_low % (4 << 10)) + (4 << 10);
	}
	auto before_last_b = memory_block.base_addr_low + memory_block.length_low - (1 << 16);
	if (memory_block.base_addr_low >= mem_beg)
	{

		for (auto it = memory_block.base_addr_low; it <= before_last_b; it += 1 << 16)
		{
			Physical::memory->add_block((char *)it);
			++block_count;
		}
	}
	else if (memory_block.base_addr_low + memory_block.length_low >= mem_beg)
	{

          for (auto it = mem_beg; it <= before_last_b; it += 1 << 16) {

            Physical::memory->add_block((char *)it);

            ++block_count;
		}
	}
}

uint64_t initialize(multiboot_memory_map_t *mmap, size_t len)
{
	multiboot_memory_map32_t *map = (multiboot_memory_map32_t *)mmap;
	Physical::memory = new ((void *)0x01000000)
		Physical::physical_layout((char *)(0x01000000 + (1 << 12)), 4 << 20);
	for (uint32_t i = 0; i < len; i++)
		if (map[i].type == 1)
			handle_usable_memory_block(map[i]);

	Physical::physical_memory = block_count << 16;

	page_dir = new (Physical::memory->malloc(sizeof(page_dir))) page_directory();

	return Physical::physical_memory;
}
} // namespace Paging

Changes to src/smp/thread.cpp.

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
#include <smp/MAGIC.hpp>
#include <libk/memory.h>
#include "config.h"
#include "smp/eslibk/_catchers.hpp"

thread::thread(size_t stack_sz, size_t metaheap_sz)
{
	auto stack_ptr=(char*)malloc(stack_sz);
	auto n=metaheap_sz%sizeof(arena);
	auto metaheap_ptr=(arena*)malloc(metaheap_sz-n);
	if(stack_ptr!=nullptr && metaheap_ptr!=nullptr)
	{
		stack=ksdk::buffer<char>(stack_ptr,stack_sz);
		metaheap=ksdk::buffer<arena>(metaheap_ptr,metaheap_sz);
		for(auto n : stack)
			n=0;
		for(auto n : metaheap)
			n=0;
		ready=true;
	}
	ready=false;
	terminated=false;
}

void thread_shim()
{
	thread* me;
	if constexpr (config::current_arch == config::arch::ix86)
	{
		char base[1];
		me=get_threading_data_hinted(base);

	}
	me->terminated=true;
}

void thread::start()
{

	if(!ready)return;
	uint32_t* magic_head;
	thread** threadptr;
	uint32_t* magic_trail;
	static_assert(config::current_arch == config::arch::ix86, "Only ix86 arch is supported by this code");
	if constexpr (config::current_arch == config::arch::ix86)
	{
		magic_head=(uint32_t*)(stack.end()-4);
		static_assert(sizeof(void*)==4, "ix86 assumption to have 32bit pointers not met");
		threadptr=(thread**)(stack.end()-8);
		magic_trail=(uint32_t*)(stack.end()-12);
	}
	*magic_head=thread_local_header;
	*threadptr=this;
	*magic_trail=thread_local_trailer;
}

void thread::pause()
{

}

void thread::resume()
{

}






|
|
|
|

|
|
|
|
|
|
|

|
|




|



|
|
<
|




>
|
|
|
|



|
|
|
|

|
|
|




<




|
<
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

#include <smp/MAGIC.hpp>
#include <libk/memory.h>
#include "config.h"
#include "smp/eslibk/_catchers.hpp"

thread::thread(size_t stack_sz, size_t metaheap_sz)
{
	auto stack_ptr = (char *)malloc(stack_sz);
	auto n = metaheap_sz % sizeof(arena);
	auto metaheap_ptr = (arena *)malloc(metaheap_sz - n);
	if (stack_ptr != nullptr && metaheap_ptr != nullptr)
	{
		stack = ksdk::buffer<char>(stack_ptr, stack_sz);
		metaheap = ksdk::buffer<arena>(metaheap_ptr, metaheap_sz);
		for (auto &n : stack)
			n = 0;
		for (auto &n : metaheap)
			n = 0;
		ready = true;
	}
	ready = false;
	terminated = false;
}

void thread_shim()
{
	thread *me;
	if constexpr (config::current_arch == config::arch::ix86)
	{
		char base[1];
		me = get_threading_data_hinted(base);
	}

	me->terminated = true;
}

void thread::start()
{
	if (!ready)
		return;
	uint32_t *magic_head;
	thread **threadptr;
	uint32_t *magic_trail;
	static_assert(config::current_arch == config::arch::ix86, "Only ix86 arch is supported by this code");
	if constexpr (config::current_arch == config::arch::ix86)
	{
		magic_head = (uint32_t *)(stack.end() - 4);
		static_assert(sizeof(void *) == 4, "ix86 assumption to have 32bit pointers not met");
		threadptr = (thread **)(stack.end() - 8);
		magic_trail = (uint32_t *)(stack.end() - 12);
	}
	*magic_head = thread_local_header;
	*threadptr = this;
	*magic_trail = thread_local_trailer;
}

void thread::pause()
{

}

void thread::resume()
{
}

Changes to src/termutils/terminal.cpp.

1
2
3
4
5





6
7
8
9
10
11
12
13
14

15
16
17
18
#include "termutils/terminal.h"

size_t Termutils::tab_size;
Termutils::terminal_output Termutils::cout;
Termutils::endl_t Termutils::endl;






void Termutils::initialize()
{
	tab_size = 4;
	cout.mode = Termutils::terminal_output::int_mode::dec;
}

template <>
Termutils::terminal_output &Termutils::terminal_output::operator<<(ksdk::string_view s)

{
	Termutils::write(s.begin(), s.size());
	return *this;
}




>
>
>
>
>



|
|



|
>

|
|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include "termutils/terminal.h"

size_t Termutils::tab_size;
Termutils::terminal_output Termutils::cout;
Termutils::endl_t Termutils::endl;
VGA::color_mode Termutils::cl_error = VGA::make_color_mode(VGA::color::RED);
VGA::color_mode Termutils::cl_success = VGA::make_color_mode(VGA::color::GREEN);
VGA::color_mode Termutils::cl_text = VGA::make_color_mode(VGA::color::WHITE);
VGA::color_mode Termutils::cl_passive = VGA::make_color_mode(VGA::color::LIGHT_GREY);
VGA::color_mode Termutils::cl_info = VGA::make_color_mode(VGA::color::LIGHT_BLUE);

void Termutils::initialize()
{
    tab_size = 4;
    cout.representation_base = Termutils::terminal_output::int_mode::dec;
}

template <>
Termutils::terminal_output &Termutils::terminal_output::
operator<<(ksdk::string_view s)
{
    Termutils::write(s.begin(), s.size());
    return *this;
}

Changes to src/tests/ATA_test.cpp.

1
2
3
4

5

6
7
8

#include "termutils/terminal.h"
#include "drivers/drivers.h"

namespace TH {

	bool ata_test () {

		return true;
	}
}



|
>
|
>
|
|
<
>
1
2
3
4
5
6
7
8
9

10
#include "termutils/terminal.h"
#include "drivers/drivers.h"

namespace TH
{
bool ata_test()
{
	return true;
}

} // namespace TH

Deleted src/tests/__register_tests.cpp.

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
#include "buffers/string_view"
#include "termutils/terminal.h"
#include "libk/string.h"
#include "config.h"

namespace TH
{
int runned;
int success;

bool run_test(bool(fn)(void), ksdk::string_view str)
{
	static const ksdk::string_view ko = ksdk::string_view((char *)"KO", 2);
	runned++;
	int ok = fn();
	success += ok;
	if (!ok)
	{
		auto red = VGA::make_color_mode(VGA::color::RED);
		auto white = VGA::make_color_mode(VGA::color::WHITE);
		Termutils::cout << str << " [" << red << ko << white << "]" << Termutils::endl;
	}
	return ok;
}

bool run_test(bool(fn)(void), const char *str)
{
	return run_test(fn, ksdk::string_view((char *)str, strlen(str)));
}

extern bool sosa_tree_test();
extern bool ata_test();
extern bool acpi_test();
extern bool lma_alloc_test();
extern bool gdt_test();

void TESTS_REGISTER()
{
	if constexpr (config::test_build)
	{
		run_test(sosa_tree_test, "SOSA Tree datastructure");
		run_test(ata_test, "(S)ATA-DRIVES");
		run_test(acpi_test, "ACPI");
		run_test(lma_alloc_test, "LMA Allocator");
		run_test(gdt_test, "GDT");

		Termutils::cout << runned << " test done, " << runned - success << " failures" << Termutils::endl;
	}
}
} // namespace TH
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































Changes to src/tests/acpi_test.cpp.

1


2
3
4




5


6
7
8

#include "acpi/acpi_access.h"



namespace TH {
	using namespace ACPI;




	bool acpi_test() {


		return true;
	}
}

|
>
>
|
<
|
>
>
>
>
|
>
>
|
|
<
>
1
2
3
4

5
6
7
8
9
10
11
12
13
14

15
#include "tests/test_utils.hpp"
#include "tests/acpi_tests/wrapper_test.hpp"
namespace TH
{

namespace ACPI_TEST
{
test_result tr;
}

test_result acpi_test()
{
	ACPI_TEST::TEST_WRAPPERS();
	return ACPI_TEST::tr;
}

} // namespace TH

Added src/tests/ksdk_test.cpp.








































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include "tests/test_utils.hpp"
#include "tests/ksdk_tests/sosa_tree_tests.hpp"
#include "tests/ksdk_tests/buffer_test.hpp"
#include "libk/memory.h"

namespace TH
{
namespace KSDK_TEST
{
test_result tr;
} // namespace KSDK_TEST

test_result ksdk_test()
{
    KSDK_TEST::SOSA_TREE_TEST();
    KSDK_TEST::BUFFER_TEST();

    return KSDK_TEST::tr;
}
} // namespace TH

Deleted src/tests/sosa_tree_test.cpp.

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
#include "buffers/sosa_tree.hpp"
#include "termutils/terminal.h"

namespace TH
{

	void dump_sosa_tree(ksdk::sosa_tree<int> tree)
	{
		for(auto i : tree.buffer())
		{
			if(i.set)
			{
				Termutils::cout<<i.elem<<",";
			}
			else
			{
				Termutils::cout<<"_"<<",";
			}
		}
		Termutils::cout<<Termutils::endl;
	}
	
	bool sosa_tree_test(){
		int subtest=1;

		ksdk::sosa_tree<int> tree(5);
		tree.insert(4);
		tree.insert(2);
		tree.insert(6);
		tree.insert(1);
		tree.insert(5);
		tree.insert(3);
		tree.insert(7);
		
		auto it = tree.find(7);
		if(it.pos==0)
		{
			Termutils::cout<<"Test #"<<subtest<<" failed"<<Termutils::endl;
			return false;
		}subtest++;

		it = tree.find(5);
		++it;
		if(*it!=6)
		{
			Termutils::cout<<"Test #"<<subtest<<" failed with value "<<*it<<Termutils::endl;
			dump_sosa_tree(tree);
			return false;
		}subtest++;

		it = tree.find(5);
		tree.remove(it.pos);
		it = tree.find(5);
		if(it.pos!=0)
		{
			Termutils::cout<<"Test #"<<subtest<<" failed"<<Termutils::endl;
			return false;
		}subtest++;
		it = tree.find(4);
		++it;
		if(*it!=6)
		{
			Termutils::cout<<"Test #"<<subtest<<" failed"<<Termutils::endl;
			return false;
		}subtest++;

		return true;
	}
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































Added src/tests/stl_test.cpp.








































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include "tests/stl_tests/vector_tests.hpp"
#include "tests/stl_tests/type_trait_tests.hpp"
#include "tests/stl_tests/vector_iterator_tests.hpp"

namespace TH
{
namespace KSTD_TEST
{
test_result tr;
} // namespace KSTD_TEST

test_result stl_test()
{
    KSTD_TEST::VECTOR_TEST{};
    KSTD_TEST::TYPE_TRAITS_TEST{};
    KSTD_TEST::VECTOR_ITERATOR_TEST{};

    return KSTD_TEST::tr;
}
} // namespace TH

Added src/tests/tests.cpp.




























































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#include "buffers/string_view"
#include "termutils/terminal.h"
#include "libk/string.h"
#include "config.h"
#include "tests/test_utils.hpp"

namespace TH
{

void write_result(bool result)
{
	if (result)
		Termutils::cout << "[" << Termutils::cl_success << "OK" << Termutils::cl_text << "] ";
	else
		Termutils::cout << "[" << Termutils::cl_error << "KO" << Termutils::cl_text << "] ";
}

bool run_test(test_result(fn)(void), ksdk::string_view str)
{
	test_result tr = fn();
	if (tr.success)
		return true;
	write_result(tr.success);
	Termutils::cout << tr.number_of_subunit_tests << " Tests passed in " << str << Termutils::cl_passive << " - " << tr.number_of_fails << " Failed - " << Termutils::cl_info << " (" << tr.comment << ")\n"
					<< Termutils::cl_text;
	return tr.success;
}

bool run_test(bool(fn)(void), ksdk::string_view str)
{
	bool ok = fn();
	if (ok)
		return true;
	write_result(ok);
	Termutils::cout << str << "\n";
	return ok;
}

template <class T>
bool run_test(T(fn)(void), const char *str)
{
	return run_test(fn, ksdk::string_view((char *)str, strlen(str)));
}

extern bool ata_test();
extern test_result acpi_test();
extern bool lma_alloc_test();
extern test_result stl_test();
extern test_result ksdk_test();

void RUN_TESTS()
{
	if constexpr (config::test_build)
	{
		run_test(stl_test, "STANDARD LIBRARY");
		run_test(ksdk_test, "KSDK");
		run_test(acpi_test, "ACPI");
		run_test(ata_test, "(S)ATA-DRIVES");
		run_test(lma_alloc_test, "LMA Allocator");
	}
}
} // namespace TH