compile-time memory::unit

neondev9
neondev9
include "memory_unit.h"

constexpr void Foo()
{
	using namespace memory::literals;

	constexpr memory::bits	    a1{1};
	constexpr memory::bytes	    a2{1};
	constexpr memory::kilobytes a3{1};
	constexpr memory::megabytes a4{1};
	constexpr memory::gigabytes a5{1};
	constexpr memory::terabytes a6{1};

	constexpr memory::kilobits  a7{1}; // kilobits!
	constexpr memory::megabits  a8{1};
	constexpr memory::gigabits  a9{1};

	constexpr memory::nibbles   b1{1}; // 4 bits
	constexpr memory::words	    b2{1}; // platform_type
	// literals
	constexpr memory::bits      literal_1 = 1bit;
	constexpr memory::bytes	    literal_2 = 1byte;
	constexpr memory::kilobytes literal_3 = 1kb;
	constexpr memory::megabytes literal_4 = 1mb;
	constexpr memory::gigabytes literal_5 = 1gb;
	constexpr memory::terabytes literal_6 = 1tb;
										  
	constexpr memory::kilobits  literal_7 = 1kbit; 
	constexpr memory::megabits  literal_8 = 1mbit;
	constexpr memory::gigabits  literal_9 = 1gbit;
	// floating-point literals + conversion
	constexpr memory::bytes	    e1 = 2.5mb; // 2621440 bytes
	constexpr memory::kilobytes e2 = 2.5mb; // 2560 kilobytes
	// conversion
	constexpr memory::bits	    d1 = 1byte; // d3.count() returned 8
	constexpr memory::bytes	    d2 = 1kb;	// ok: kilobyte > byte
	constexpr memory::bytes	    d3 = 100mb;	// ok: megabyte > byte
	constexpr memory::megabytes d4 = 2gb;	// ok: gigabyte > megabyte

	constexpr memory::kilobytes error = 512byte; // error C2440: cannot convert from "memory::bytes" to "memory::kilobytes"
	// but...
	constexpr memory::kilobytes not_error1 = memory::unit_cast<memory::kilobytes>(1024byte); // 1 kilobytes
	constexpr memory::kilobytes not_error2 = memory::floor<memory::kilobytes>(2561byte);	 // 2 kilobytes
	constexpr memory::kilobytes not_error3 = memory::ceil <memory::kilobytes>(2561byte);	 // 3 kilobytes
	constexpr memory::kilobytes not_error4 = memory::round<memory::kilobytes>(2561byte);	 // 3 kilobytes

	constexpr auto floating_point_type = 1.25kb; // typeid: memory::unit<long_double, memory::internal_ratio::kilobytes>
	// arithmetic
	constexpr auto f1 = 3kb + 5kb;  // memory::killobytes{8}
	constexpr auto f2 = 3kb + 5mb;  // 3 kilobytes + 5 megabytes = memory::kilobytes{5123}

	constexpr auto f3 = f2 + 5byte; // 5123 kilobytes + 5 bytes = memory::bytes{5245957}
	constexpr auto f4 = 1gb + 512mb - 100kb; // 1 gigabyte + 512 megabyte - 100 kilobytes = memory::kilobytes{1572764}
	// mixed arithmetic: double + long long int + double
	constexpr auto f5 = 1.25kb + 1mb + 0.07mb; // 1096.93 kilobytes

	// comparison
	constexpr bool g1{ 1kb == 1024byte }; // true
	constexpr bool g2{ 512mb != 0.5gb };  // false
	constexpr bool g3{ 1mb > 1kb };	      // true
	constexpr bool g4{ 1tb < 1gb };	      // false

}
2
рейтинг
4 комментария
yndx-antoshkka

Идея хорошая, но стоит ещё сделать и другие типы данных (физические типы данных, например скорость, ускорение, масса и т.д.)

yndx-antoshkka
Artalus

В качестве отправной точки можно также взять вот такое чудо.

Artalus
neondev9

Artalus, отличная библиотека. Используется та же концепция, но объём впечатляет)

Сегодня еще искал в boost подобные штуки, нашёл boost::units, суть практически та же, но подход другой и внешний вид не впечатляет.

neondev9
Обновлено 
Andrey Davydov

Это ж можно будет писать

std::byte buffer[4mb / 1byte];

вообще красота!

А `1byte / 1bit` предлагаете сделать платформозависимой константой?

И еще, если сама идея такой библиотеки продвинется до обсуждения в комитете, то по поводу именования суффиксов будут очень жаркие дебаты.

Andrey Davydov
Другие идеи
Группа создана, чтобы собирать предложения к стандарту C++, организовывать их внутренние обсуждения, помогать готовить их для отправки в комитет и защищать на общих собраниях в рабочей группе по С++ Международной организации по стандартизации (ISO).
Все предложения