// SPDX-License-Identifier: 0BSD

#pragma once

#include <sys/mman.h>


namespace vore::file {
	namespace {
		class mapping {
		public:
			constexpr mapping() noexcept {}

			mapping(void * addr, std::size_t length, int prot, int flags, int fd) noexcept {
				void * ret = mmap(addr, length, prot, flags, fd, 0);
				if(ret != MAP_FAILED) {
					this->map    = {static_cast<std::uint8_t *>(ret), length};
					this->opened = true;
				}
			}

			mapping(const mapping &) = delete;
			constexpr mapping(mapping && oth) noexcept : map(oth.map), opened(oth.opened) { oth.opened = false; }

			constexpr mapping & operator=(mapping && oth) noexcept {
				this->map    = oth.map;
				this->opened = oth.opened;
				oth.opened   = false;
				return *this;
			}

			~mapping() {
				if(this->opened)
					munmap(const_cast<std::uint8_t *>(this->map.data()), this->map.size());
			}

			constexpr operator bool() const noexcept { return !this->map.empty(); }
			constexpr operator std::basic_string_view<std::uint8_t>() const noexcept { return this->map; }
			constexpr const std::basic_string_view<std::uint8_t> & operator*() const noexcept { return this->map; }
			constexpr const std::basic_string_view<std::uint8_t> * operator->() const noexcept { return &this->map; }


		private:
			std::basic_string_view<std::uint8_t> map = {};
			bool opened                              = false;
		};
	}
}
