From 70a49f2e4a9ab05fe04d1949bbf7a128d14a1284 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 9 May 2019 14:35:15 -0700 Subject: [PATCH] [meta] Add hb_conditional<> and hb_is_convertible() --- src/Makefile.am | 6 ++++- src/hb-meta.hh | 56 +++++++++++++++++++++++++++++++------- src/test-meta.cc | 70 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 121 insertions(+), 11 deletions(-) create mode 100644 src/test-meta.cc diff --git a/src/Makefile.am b/src/Makefile.am index 9b5512f20..fc772e0ac 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -384,7 +384,7 @@ dump_use_data_SOURCES = dump-use-data.cc hb-ot-shape-complex-use-table.cc dump_use_data_CPPFLAGS = $(HBCFLAGS) dump_use_data_LDADD = libharfbuzz.la $(HBLIBS) -COMPILED_TESTS = test-algs test-iter test-ot-tag test-unicode-ranges +COMPILED_TESTS = test-algs test-iter test-meta test-ot-tag test-unicode-ranges COMPILED_TESTS_CPPFLAGS = $(HBCFLAGS) -DMAIN -UNDEBUG COMPILED_TESTS_LDADD = libharfbuzz.la $(HBLIBS) check_PROGRAMS += $(COMPILED_TESTS) @@ -398,6 +398,10 @@ test_iter_SOURCES = test-iter.cc hb-static.cc test_iter_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS) test_iter_LDADD = $(COMPILED_TESTS_LDADD) +test_meta_SOURCES = test-meta.cc hb-static.cc +test_meta_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS) +test_meta_LDADD = $(COMPILED_TESTS_LDADD) + test_ot_tag_SOURCES = hb-ot-tag.cc test_ot_tag_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS) test_ot_tag_LDADD = $(COMPILED_TESTS_LDADD) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index 74a4457c3..b2344f78c 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -52,6 +52,18 @@ typedef hb_bool_tt hb_true_t; typedef hb_bool_tt hb_false_t; +/* Basic type SFINAE. */ + +template struct hb_enable_if {}; +template struct hb_enable_if { typedef T type; }; +#define hb_enable_if(Cond) typename hb_enable_if<(Cond)>::type* = nullptr +/* Concepts/Requires alias: */ +#define hb_requires(Cond) hb_enable_if((Cond)) + +template struct hb_is_same : hb_false_t {}; +template struct hb_is_same : hb_true_t {}; +#define hb_is_same(T, T2) hb_is_same::value + /* Function overloading SFINAE and priority. */ #define HB_RETURN(Ret, E) -> hb_head_tt { return (E); } @@ -110,6 +122,40 @@ template using hb_decay = hb_remove_const>; hb_is_reference (A) >= hb_is_reference (B)) + +template +struct _hb_conditional { typedef T type; }; +template +struct _hb_conditional { typedef F type; }; +template +using hb_conditional = typename _hb_conditional::type; + + +template +struct hb_is_convertible +{ + private: + static constexpr bool from_void = hb_is_same (void, hb_decay); + static constexpr bool to_void = hb_is_same (void, hb_decay ); + static constexpr bool either_void = from_void || to_void; + static constexpr bool both_void = from_void && to_void; + + static hb_true_t impl2 (hb_conditional); + + template + static auto impl (hb_priority<1>) HB_AUTO_RETURN ( impl2 (hb_declval (T)) ) + template + static hb_false_t impl (hb_priority<0>); + public: + static constexpr bool value = both_void || + (!either_void && + decltype (impl> (hb_prioritize))::value); +}; + + +#define hb_is_convertible(From,To) hb_is_convertible::value + + /* std::move and std::forward */ template @@ -162,16 +208,6 @@ struct hb_reference_wrapper }; -template struct hb_enable_if {}; -template struct hb_enable_if { typedef T type; }; -#define hb_enable_if(Cond) typename hb_enable_if<(Cond)>::type* = nullptr -/* Concepts/Requires alias: */ -#define hb_requires(Cond) hb_enable_if((Cond)) - -template struct hb_is_same : hb_false_t {}; -template struct hb_is_same : hb_true_t {}; -#define hb_is_same(T, T2) hb_is_same::value - template struct hb_is_signed; template <> struct hb_is_signed { static constexpr bool value = CHAR_MIN < 0; }; template <> struct hb_is_signed { static constexpr bool value = true; }; diff --git a/src/test-meta.cc b/src/test-meta.cc new file mode 100644 index 000000000..a7cfef5a4 --- /dev/null +++ b/src/test-meta.cc @@ -0,0 +1,70 @@ +/* + * Copyright © 2019 Facebook, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Facebook Author(s): Behdad Esfahbod + */ + +#include "hb.hh" +#include "hb-meta.hh" + + +int +main (int argc, char **argv) +{ + + static_assert (hb_is_convertible (void, void)); + static_assert (hb_is_convertible (void, const void)); + static_assert (hb_is_convertible (const void, void)); + + static_assert (hb_is_convertible (int, int)); + static_assert (hb_is_convertible (char, int)); + static_assert (hb_is_convertible (long, int)); + + static_assert (hb_is_convertible (int, int)); + + static_assert (hb_is_convertible (const int, int)); + static_assert (hb_is_convertible (int, const int)); + static_assert (hb_is_convertible (const int, const int)); + + static_assert (hb_is_convertible (int&, int)); + static_assert (!hb_is_convertible (int, int&)); + + static_assert (hb_is_convertible (int, const int&)); + static_assert (!hb_is_convertible (const int, int&)); + static_assert (hb_is_convertible (const int, const int&)); + static_assert (hb_is_convertible (int&, const int)); + static_assert (hb_is_convertible (const int&, int)); + static_assert (hb_is_convertible (const int&, const int)); + + static_assert (hb_is_convertible (int&, long)); + static_assert (!hb_is_convertible (int&, long&)); + + static_assert (hb_is_convertible (int *, int *)); + static_assert (hb_is_convertible (int *, const int *)); + static_assert (!hb_is_convertible (const int *, int *)); + static_assert (!hb_is_convertible (int *, long *)); + static_assert (hb_is_convertible (int *, void *)); + static_assert (!hb_is_convertible (void *, int *)); + + return 0; +}