<commit_before>/** 
 * @file llunit.h
 * @brief Unit conversion classes
 *
 * $LicenseInfo:firstyear=2001&license=viewerlgpl$
 * Second Life Viewer Source Code
 * Copyright (C) 2012, Linden Research, Inc.
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * version 2.1 of the License only.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * 
 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 * $/LicenseInfo$
 */

#ifndef LL_LLUNIT_H
#define LL_LLUNIT_H

#include "stdtypes.h"
#include "llpreprocessor.h"

template<typename STORAGE_TYPE, typename BASE_UNIT, typename DERIVED_UNIT = BASE_UNIT>
struct LLUnitType : public BASE_UNIT
{
	typedef DERIVED_UNIT unit_t;

	typedef typename STORAGE_TYPE storage_t;
	typedef void is_unit_tag_t;

	LLUnitType()
	{}

	explicit LLUnitType(storage_t value)
	:	BASE_UNIT(convertToBase(value))
	{}

	// implicit downcast
	operator unit_t& ()
	{
		return static_cast<unit_t&>(*this);
	}

	storage_t value() const
	{
		return convertToDerived(mBaseValue);
	}

	template<typename CONVERTED_TYPE>
	storage_t as() const
	{
		return CONVERTED_TYPE(*this).value();
	}

protected:
	static storage_t convertToBase(storage_t derived_value)
	{
		return (storage_t)((F32)derived_value * unit_t::conversionToBaseFactor());
	}

	static storage_t convertToDerived(storage_t base_value)
	{
		return (storage_t)((F32)base_value / unit_t::conversionToBaseFactor());
	}

};

template<typename STORAGE_TYPE, typename T>
struct LLUnitType<STORAGE_TYPE, T, T>
{
	typedef T unit_t;
	typedef STORAGE_TYPE storage_t;
	typedef void is_unit_tag_t;

	LLUnitType()
	:	mBaseValue()
	{}

	explicit LLUnitType(storage_t value)
	:	mBaseValue(value)
	{}

	unit_t& operator=(storage_t value)
	{
		setBaseValue(value);
		return *this;
	}

	//implicit downcast
	operator unit_t& ()
	{
		return static_cast<unit_t&>(*this);<commit_msg>SH-3499 WIP Ensure asset stats output is correct removed explicit constructor of LLUnit from integral types, as C++ already guarantees that I can't convert from LLUnit<Bytes> to LLUnits<Seconds> (requires 2 user defined conversions).  Now this allows seamless replacement of existing integral types with Unit labeled types.<commit_after>/** 
 * @file llunit.h
 * @brief Unit conversion classes
 *
 * $LicenseInfo:firstyear=2001&license=viewerlgpl$
 * Second Life Viewer Source Code
 * Copyright (C) 2012, Linden Research, Inc.
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * version 2.1 of the License only.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * 
 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 * $/LicenseInfo$
 */

#ifndef LL_LLUNIT_H
#define LL_LLUNIT_H

#include "stdtypes.h"
#include "llpreprocessor.h"

template<typename STORAGE_TYPE, typename BASE_UNIT, typename DERIVED_UNIT = BASE_UNIT>
struct LLUnitType : public BASE_UNIT
{
	typedef DERIVED_UNIT unit_t;

	typedef typename STORAGE_TYPE storage_t;
	typedef void is_unit_tag_t;

	LLUnitType()
	{}

	LLUnitType(storage_t value)
	:	BASE_UNIT(convertToBase(value))
	{}

	// implicit downcast
	operator unit_t& ()
	{
		return static_cast<unit_t&>(*this);
	}

	storage_t value() const
	{
		return convertToDerived(mBaseValue);
	}

	template<typename CONVERTED_TYPE>
	storage_t as() const
	{
		return CONVERTED_TYPE(*this).value();
	}

protected:
	static storage_t convertToBase(storage_t derived_value)
	{
		return (storage_t)((F32)derived_value * unit_t::conversionToBaseFactor());
	}

	static storage_t convertToDerived(storage_t base_value)
	{
		return (storage_t)((F32)base_value / unit_t::conversionToBaseFactor());
	}

};

template<typename STORAGE_TYPE, typename T>
struct LLUnitType<STORAGE_TYPE, T, T>
{
	typedef T unit_t;
	typedef STORAGE_TYPE storage_t;
	typedef void is_unit_tag_t;

	LLUnitType()
	:	mBaseValue()
	{}

	LLUnitType(storage_t value)
	:	mBaseValue(value)
	{}

	unit_t& operator=(storage_t value)
	{
		setBaseValue(value);
		return *this;
	}

	//implicit downcast
	operator unit_t& ()
	{
		return static_cast<unit_t&>(*this);
{'fraction_non_alphanumeric': 0.08870341614906832, 'fraction_numerical': 0.013781055900621118, 'mean_word_length': 4.763982102908278, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1323120', 'n_tokens_mistral': 1789, 'n_tokens_neox': 1648, 'n_words': 526}