/** * @file lldefs.h * @brief Various generic constant definitions. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, 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_LLDEFS_H #define LL_LLDEFS_H #include "stdtypes.h" #include #include // Often used array indices constexpr U32 VX = 0; constexpr U32 VY = 1; constexpr U32 VZ = 2; constexpr U32 VW = 3; constexpr U32 VS = 3; constexpr U32 VRED = 0; constexpr U32 VGREEN = 1; constexpr U32 VBLUE = 2; constexpr U32 VALPHA = 3; constexpr U32 INVALID_DIRECTION = 0xFFFFFFFF; constexpr U32 EAST = 0; constexpr U32 NORTH = 1; constexpr U32 WEST = 2; constexpr U32 SOUTH = 3; constexpr U32 NORTHEAST = 4; constexpr U32 NORTHWEST = 5; constexpr U32 SOUTHWEST = 6; constexpr U32 SOUTHEAST = 7; constexpr U32 MIDDLE = 8; constexpr U8 EAST_MASK = 0x1< X // |/| | -4- |/| | // | +----|---------|---+ // | / / | / // | / -6- | / // |/ / |/ // +------------------+ constexpr U32 NO_SIDE = 0; constexpr U32 FRONT_SIDE = 1; constexpr U32 BACK_SIDE = 2; constexpr U32 LEFT_SIDE = 3; constexpr U32 RIGHT_SIDE = 4; constexpr U32 TOP_SIDE = 5; constexpr U32 BOTTOM_SIDE = 6; constexpr U8 LL_SOUND_FLAG_NONE = 0x0; constexpr U8 LL_SOUND_FLAG_LOOP = 1<<0; constexpr U8 LL_SOUND_FLAG_SYNC_MASTER = 1<<1; constexpr U8 LL_SOUND_FLAG_SYNC_SLAVE = 1<<2; constexpr U8 LL_SOUND_FLAG_SYNC_PENDING = 1<<3; constexpr U8 LL_SOUND_FLAG_QUEUE = 1<<4; constexpr U8 LL_SOUND_FLAG_STOP = 1<<5; constexpr U8 LL_SOUND_FLAG_SYNC_MASK = LL_SOUND_FLAG_SYNC_MASTER | LL_SOUND_FLAG_SYNC_SLAVE | LL_SOUND_FLAG_SYNC_PENDING; // // *NOTE: These values may be used as hard-coded numbers in scanf() variants. // // -------------- // DO NOT CHANGE. // -------------- // constexpr U32 LL_MAX_PATH = 1024; // buffer size of maximum path + filename string length // For strings we send in messages constexpr U32 STD_STRING_BUF_SIZE = 255; // Buffer size constexpr U32 STD_STRING_STR_LEN = 254; // Length of the string (not including \0) // *NOTE: This value is used as hard-coded numbers in scanf() variants. // DO NOT CHANGE. constexpr U32 MAX_STRING = STD_STRING_BUF_SIZE; // Buffer size constexpr U32 MAXADDRSTR = 17; // 123.567.901.345 = 15 chars + \0 + 1 for good luck // C++ is our friend. . . use template functions to make life easier! // specific inlines for basic types // // defined for all: // llmin(a,b) // llmax(a,b) // llclamp(a,minimum,maximum) // // defined for F32, F64: // llclampf(a) // clamps a to [0.0 .. 1.0] // // defined for U16, U32, U64, S16, S32, S64, : // llclampb(a) // clamps a to [0 .. 255] // // llless(d0, d1) safely compares d0 < d1 even if one is signed and the other // is unsigned. A simple (d0 < d1) expression converts the signed operand to // unsigned before comparing. If the signed operand is negative, that flips // the negative value to a huge positive value, producing the wrong answer! // llless() specifically addresses that case. template constexpr bool llless(T0 d0, T1 d1) { if constexpr (std::is_signed_v && ! std::is_signed_v) { // T0 signed, T1 unsigned: negative d0 is less than any unsigned d1 if (d0 < 0) return true; // both are non-negative: explicitly cast to avoid C4018 return std::make_unsigned_t(d0) < d1; } else if constexpr (! std::is_signed_v && std::is_signed_v) { // T0 unsigned, T1 signed: any unsigned d0 is greater than negative d1 if (d1 < 0) return false; // both are non-negative: explicitly cast to avoid C4018 return d0 < std::make_unsigned_t(d1); } else { // both T0 and T1 are signed, or both are unsigned: // straightforward comparison works return d0 < d1; } } // recursion tail template constexpr auto llmax(T data) { return data; } template constexpr auto llmax(T0 d0, T1 d1, Ts... rest) { auto maxrest = llmax(d1, rest...); return llless(maxrest, d0)? d0 : maxrest; } // recursion tail template constexpr auto llmin(T data) { return data; } template constexpr auto llmin(T0 d0, T1 d1, Ts... rest) { auto minrest = llmin(d1, rest...); return llless(d0, minrest) ? d0 : minrest; } template constexpr A llclamp(A a, MIN minval, MAX maxval) { // The only troublesome case is if A is unsigned and either minval or // maxval is both signed and negative. Casting a negative number to // unsigned flips it to a huge positive number, making this llclamp() call // ineffective. if constexpr (! std::is_signed_v) { if constexpr (std::is_signed_v) { assert(minval >= 0); } if constexpr (std::is_signed_v) { assert(maxval >= 0); } } A aminval{ static_cast(minval) }, amaxval{ static_cast(maxval) }; if ( a < aminval ) { return aminval; } else if ( a > amaxval ) { return amaxval; } return a; } template constexpr LLDATATYPE llclampf(LLDATATYPE a) { return llmin(llmax(a, LLDATATYPE(0)), LLDATATYPE(1)); } template constexpr LLDATATYPE llclampb(LLDATATYPE a) { return llmin(llmax(a, LLDATATYPE(0)), LLDATATYPE(255)); } template inline void llswap(LLDATATYPE& lhs, LLDATATYPE& rhs) { std::swap(lhs, rhs); } #endif // LL_LLDEFS_H