/*
 * Copyright 2015 - 2025 gary@drinkingtea.net
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */

#pragma once

#if __has_include(<source_location>)

#include <source_location>

#else

#include "types.hpp"

namespace std {

class source_location {
	private:
		struct __impl {
			char const*_M_file_name{};
			char const*_M_function_name{};
			uint32_t _M_line{};
			uint32_t _M_column{};
		};
		static constexpr __impl Default{
			._M_file_name = "",
			._M_function_name = "",
			._M_line = {},
			._M_column = {},
		};
		__impl const*m_data{&Default};
		using Raw = decltype(__builtin_source_location());

	public:
		constexpr source_location() noexcept = default;

		static consteval source_location current(Raw const pSl = __builtin_source_location()) noexcept {
			source_location sl;
			if (pSl) {
				sl.m_data = static_cast<__impl const*>(pSl);
			}
			return sl;
		}

		constexpr uint32_t line() const noexcept {
			return m_data->_M_line;
		}

		constexpr uint32_t column() const noexcept {
			return m_data->_M_column;
		}

		constexpr ox::CString file_name() const noexcept {
			return m_data->_M_file_name;
		}

		constexpr ox::CString function_name() const noexcept {
			return m_data->_M_function_name;
		}
};

}

#endif
