/****************************************************************************** mkid: map chars to int at build time. Template based. A replacement of FourCC Copyright (C) 2012-2014 Wang Bin 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; either version 2.1 of the License, or (at your option) any later version. 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 ******************************************************************************/ #ifndef MKID_H #define MKID_H /*! * Example: * int id1 = mkid::fourcc<'H', 'E', 'V', 'C'>::value; * int id2 = mkid::id32base64_5<'H', 'e', 'l', 'l', 'o'>::value; * int id3 = mkid::id32base36_6<'M', 'r', 'W', 'a', 'n', 'g'>::value; * For (u)int32 result, base 64 accepts at most 5 characters, while base 36 accepts at most 6 characters. */ namespace mkid { namespace detail { template struct map_base; } // namespace internal template struct id32_1 { enum { value = detail::map_base::value};}; template struct id32_2 { enum { value = id32_1::value*base + detail::map_base::value};}; template struct id32_3 { enum { value = id32_2::value*base + detail::map_base::value};}; template struct id32_4 { enum { value = id32_3::value*base + detail::map_base::value};}; template struct id32_5 { enum { value = id32_4::value*base + detail::map_base::value};}; template struct id32_6 { enum { value = id32_5::value*base + detail::map_base::value};}; // template based FourCC template struct fourcc : public id32_4<256, a0, a1, a2, a3>{}; // a0~a4: '0'~'9', 'A'~'Z', 'a'~'z', '_', '.' ==>> [0,63] template struct id32base64_1 : public id32_1<64, a0>{}; template struct id32base64_2 : public id32_2<64, a0, a1>{}; template struct id32base64_3 : public id32_3<64, a0, a1, a2>{}; template struct id32base64_4 : public id32_4<64, a0, a1, a2, a3>{}; template struct id32base64_5 : public id32_5<64, a0, a1, a2, a3, a4>{}; // a0~a5: '0'~'9', 'A'~'Z', 'a'~'z' ==>> [0,63], upper and lower letters are equal template struct id32base36_1 : public id32_1<36, a0>{}; template struct id32base36_2 : public id32_2<36, a0, a1>{}; template struct id32base36_3 : public id32_3<36, a0, a1, a2>{}; template struct id32base36_4 : public id32_4<36, a0, a1, a2, a3>{}; template struct id32base36_5 : public id32_5<36, a0, a1, a2, a3, a4>{}; template struct id32base36_6 : public id32_6<36, a0, a1, a2, a3, a4, a5>{}; namespace detail { ////////////////////////////Details//////////////////////////// template struct if_then_else; template struct if_then_else { typedef T1 Type;}; template struct if_then_else { typedef T2 Type;}; template struct is_lower_letter { enum { value = c >= 97 && c <= 122 };}; template struct is_upper_letter { enum { value = c >= 65 && c <= 90 };}; template struct is_num { enum { value = c >= 48 && c <= 57 };}; template struct is_underline { enum { value = c == 95 }; }; template struct is_dot { enum { value = c == 46 };}; struct lower_letter_t; struct upper_letter_t; struct number_t; struct underline_t; struct dot_t; template struct map64_helper; template struct map64_helper { enum { value = x-48}; }; template struct map64_helper { enum { value = x-65+10}; }; template struct map64_helper { enum { value = x-97+10+26}; }; template struct map64_helper { enum { value = 62}; }; template struct map64_helper { enum { value = 63}; }; struct invalid_char_must_be_number_26letters_underline_dot; template struct map_base<64, x> { enum { value = map64_helper::value, number_t, typename if_then_else::value, upper_letter_t, typename if_then_else::value, lower_letter_t, typename if_then_else::value, underline_t, typename if_then_else::value, dot_t, invalid_char_must_be_number_26letters_underline_dot>::Type>::Type>::Type>::Type>::Type>::value }; }; template struct map36_helper; template struct map36_helper { enum { value = x-48}; }; template struct map36_helper { enum { value = x-65+10}; }; template struct map36_helper { enum { value = x-97+10}; }; struct invalid_char_must_be_number_26letters; template struct map_base<36, x> { enum { value = map36_helper::value, number_t, typename if_then_else::value, upper_letter_t, typename if_then_else::value, lower_letter_t, invalid_char_must_be_number_26letters>::Type>::Type>::Type>::value }; }; // for FourCC template struct out_of_lower_bound {}; template struct out_of_upper_bound {}; struct map_identical_t; template struct map_identical_helper; template struct map_identical_helper{enum{value=x};}; template struct map_base<256, x> { enum { value = map_identical_helper, typename if_then_else<(x>255), out_of_upper_bound<255>, map_identical_t>::Type>::Type>::value }; }; } // namespace detail } // namespace mkid #endif // MKID_H