From 59729a1eb691664356f723af4fc52949f1873e6e Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Mon, 7 Aug 2023 13:22:09 +0200 Subject: [PATCH] More bitmask support code * ridlbe/c++11/templates/cli/hdr/bitmask_idl_traits.erb: Added. * ridlbe/c++11/config/cxx_type.rb: * ridlbe/c++11/templates/cli/hdr/bitmask.erb: * ridlbe/c++11/visitorbase.rb: * ridlbe/c++11/visitors/bitmask.rb: * ridlbe/c++11/visitors/bitset.rb: * ridlbe/c++11/writers/stubheader.rb: * tests/idl4/bitmask/client.cpp: * tests/idl4/bitmask/test.idl: --- ridlbe/c++11/config/cxx_type.rb | 4 +- ridlbe/c++11/templates/cli/hdr/bitmask.erb | 13 +++-- .../templates/cli/hdr/bitmask_idl_traits.erb | 51 +++++++++++++++++++ ridlbe/c++11/visitorbase.rb | 2 +- ridlbe/c++11/visitors/bitmask.rb | 4 +- ridlbe/c++11/visitors/bitset.rb | 4 +- ridlbe/c++11/writers/stubheader.rb | 8 ++- tests/idl4/bitmask/client.cpp | 25 ++++++--- tests/idl4/bitmask/test.idl | 14 ++++- 9 files changed, 106 insertions(+), 19 deletions(-) create mode 100644 ridlbe/c++11/templates/cli/hdr/bitmask_idl_traits.erb diff --git a/ridlbe/c++11/config/cxx_type.rb b/ridlbe/c++11/config/cxx_type.rb index 703afbf2..514da83f 100644 --- a/ridlbe/c++11/config/cxx_type.rb +++ b/ridlbe/c++11/config/cxx_type.rb @@ -841,7 +841,7 @@ def is_pod? end end - class BitMask + class Bitmask include IdlType_Mixin def cxx_type(scope = nil) (scope && (scope == node || scope == node.enclosure)) ? node.cxxname : ('::' + node.scoped_cxxname) @@ -860,7 +860,7 @@ def is_pod? end end - class BitSet + class Bitset include IdlType_Mixin def cxx_type(scope = nil) (scope && (scope == node || scope == node.enclosure)) ? node.cxxname : ('::' + node.scoped_cxxname) diff --git a/ridlbe/c++11/templates/cli/hdr/bitmask.erb b/ridlbe/c++11/templates/cli/hdr/bitmask.erb index f3a6c4aa..920e7892 100644 --- a/ridlbe/c++11/templates/cli/hdr/bitmask.erb +++ b/ridlbe/c++11/templates/cli/hdr/bitmask.erb @@ -1,10 +1,17 @@ // generated from <%= ridl_template_path %> /// @copydoc <%= doc_scoped_name %> -enum <%= cxxname %>Bit : <%= bitbound.cxx_type %> +enum class <%= cxxname %> : <%= bitbound.cxx_type %> { <%= bitvalues.collect {|e| "/// @copydoc #{doc_scoped_name}::#{e.name}\n #{e.cxxname} = #{e.value}" }.join(",\n ") %> -};// <%= cxxname %>Bit -using <%= cxxname %> = <%= bitbound.cxx_type %>; +};// <%= cxxname %> + +inline <%= cxx_return_type %> operator~ (<%= cxx_in_type %> _taox11_t) { return static_cast<<%= cxxname %>>(~static_cast<<%= bitbound.cxx_type %>>(_taox11_t)); } +inline <%= cxx_return_type %> operator| (<%= cxx_in_type %> _taox11_t, <%= cxx_in_type %> _taox11_y) { return static_cast<<%= cxxname %>>(static_cast<<%= bitbound.cxx_type %>>(_taox11_t) | static_cast<<%= bitbound.cxx_type %>>(_taox11_y)); } +inline <%= cxx_return_type %> operator^ (<%= cxx_in_type %> _taox11_t, <%= cxx_in_type %> _taox11_y) { return static_cast<<%= cxxname %>>(static_cast<<%= bitbound.cxx_type %>>(_taox11_t) ^ static_cast<<%= bitbound.cxx_type %>>(_taox11_y)); } +inline <%= cxx_return_type %> operator& (<%= cxx_in_type %> _taox11_t, <%= cxx_in_type %> _taox11_y) { return static_cast<<%= cxxname %>>(static_cast<<%= bitbound.cxx_type %>>(_taox11_t) & static_cast<<%= bitbound.cxx_type %>>(_taox11_y)); } +inline <%= cxx_return_type %> operator |= (<%= cxx_inout_type %> _taox11_lhs, <%= cxx_in_type %> _taox11_rhs) { _taox11_lhs = _taox11_lhs | _taox11_rhs; return _taox11_lhs; } +inline <%= cxx_return_type %> operator &= (<%= cxx_inout_type %> _taox11_lhs, <%= cxx_in_type %> _taox11_rhs) { _taox11_lhs = _taox11_lhs & _taox11_rhs; return _taox11_lhs; } +inline <%= cxx_return_type %> operator ^= (<%= cxx_inout_type %> _taox11_lhs, <%= cxx_in_type %> _taox11_rhs) { _taox11_lhs = _taox11_lhs ^ _taox11_rhs; return _taox11_lhs; } % visit_template('typecode') if generate_typecode_support? diff --git a/ridlbe/c++11/templates/cli/hdr/bitmask_idl_traits.erb b/ridlbe/c++11/templates/cli/hdr/bitmask_idl_traits.erb new file mode 100644 index 00000000..d7945fed --- /dev/null +++ b/ridlbe/c++11/templates/cli/hdr/bitmask_idl_traits.erb @@ -0,0 +1,51 @@ + +// generated from <%= ridl_template_path %> +template<> +struct traits <<%= scoped_cxxtype %>> + : IDL::common_byval_traits<<%= scoped_cxxtype %>> +{ + /// Underlying type of the bitmask + using underlying_type = <%= bitbound.cxx_type %>; + + /// bit_bound + using bit_bound = std::integral_constant>; + + template > + static inline OStrm_& write_on(OStrm_& os_, in_type val_, Formatter fmt_ = Formatter ()) + { + return fmt_ (os_, val_); + } + + template + static inline __Writer write (in_type val) { return {val}; } +}; + +template +struct formatter<<%= scoped_cxxtype %>, OStrm_> +{ + inline OStrm_& operator ()(OStrm_& os_, <%= scoped_cxx_in_type %> val_) + { +% # TODO + switch (val_) + { +% bitvalues.each do |e| + +// case <%= scoped_cxxtype %>::<%=e.cxxname %>: os_ << "<%= formatted_cxxname %>::<%=e.cxxname %>"; break; +%end + } + return os_; + } +}; + +template +inline OStrm_& operator <<(OStrm_& os, IDL::traits<<%= scoped_cxxtype %>>::__Writer w) +{ + using writer_t = IDL::traits<<%= scoped_cxxtype %>>::__Writer; + using formatter_t = typename std::conditional< + std::is_same< + typename writer_t::formatter_t, + std::false_type>::value, + formatter<<%= scoped_cxxtype %>, OStrm_>, + typename writer_t::formatter_t>::type; + return IDL::traits<<%= scoped_cxxtype %>>::write_on (os, w.val_, formatter_t ()); +} diff --git a/ridlbe/c++11/visitorbase.rb b/ridlbe/c++11/visitorbase.rb index d5162768..b100e6f6 100644 --- a/ridlbe/c++11/visitorbase.rb +++ b/ridlbe/c++11/visitorbase.rb @@ -495,7 +495,7 @@ def is_stdlib_type? true when IDL::Type::Object, IDL::Type::Any, IDL::Type::Valuetype true - when IDL::Type::Enum + when IDL::Type::Enum, IDL::Type::BitMask false else self._idltype.is_pod? diff --git a/ridlbe/c++11/visitors/bitmask.rb b/ridlbe/c++11/visitors/bitmask.rb index 9d8ff131..e6166253 100644 --- a/ridlbe/c++11/visitors/bitmask.rb +++ b/ridlbe/c++11/visitors/bitmask.rb @@ -9,7 +9,7 @@ module IDL module Cxx11 - class BitMaskVisitor < NodeVisitorBase + class BitmaskVisitor < NodeVisitorBase def bitvalues @bitvalues ||= node.bitvalues.collect { |en| (ev = visitor(BitValueVisitor)).visit(en) @@ -28,7 +28,7 @@ def bitbound_bits map_template :bitmask, :bitmask map_template :typecode, :typecode - map_template :tao_typecode, :enum_typecode + map_template :tao_typecode, :bitmask_typecode end class BitValueVisitor < NodeVisitorBase diff --git a/ridlbe/c++11/visitors/bitset.rb b/ridlbe/c++11/visitors/bitset.rb index d0f4a404..c982e7ac 100644 --- a/ridlbe/c++11/visitors/bitset.rb +++ b/ridlbe/c++11/visitors/bitset.rb @@ -9,7 +9,7 @@ module IDL module Cxx11 - class BitSetVisitor < NodeVisitorBase + class BitsetVisitor < NodeVisitorBase def bitfields @bitfields ||= node.bitfields.collect { |en| (ev = visitor(BitFieldVisitor)).visit(en) @@ -21,7 +21,7 @@ def bitfields map_template :bitset, :bitset map_template :typecode, :typecode - map_template :tao_typecode, :enum_typecode + map_template :tao_typecode, :bitset_typecode end class BitFieldVisitor < NodeVisitorBase diff --git a/ridlbe/c++11/writers/stubheader.rb b/ridlbe/c++11/writers/stubheader.rb index e0d9bdf2..b676beaf 100644 --- a/ridlbe/c++11/writers/stubheader.rb +++ b/ridlbe/c++11/writers/stubheader.rb @@ -299,11 +299,11 @@ def visit_enum(node) end def visit_bitmask(node) - visitor(BitMaskVisitor).visit_bitmask(node) + visitor(BitmaskVisitor).visit_bitmask(node) end def visit_bitset(node) - visitor(BitSetVisitor).visit_bitset(node) + visitor(BitsetVisitor).visit_bitset(node) end def visit_typedef(node) @@ -514,6 +514,10 @@ def visit_enum(node) visitor(EnumVisitor).visit_idl_traits(node) end + def visit_bitmask(node) + visitor(BitmaskVisitor).visit_idl_traits(node) + end + def declare_struct(node) visitor(StructVisitor).visit_idl_traits(node) end diff --git a/tests/idl4/bitmask/client.cpp b/tests/idl4/bitmask/client.cpp index 25c923a0..32da201b 100644 --- a/tests/idl4/bitmask/client.cpp +++ b/tests/idl4/bitmask/client.cpp @@ -15,19 +15,32 @@ int main (int /*argc*/, char* /*argv*/[]) { // Just compilation test - MyBitMask my_bitmask; - MyBitMaskBit my_bitmaskbit; - X11_UNUSED_ARG(my_bitmask); - X11_UNUSED_ARG(my_bitmaskbit); + MyBitMask my_bitmask = MyBitMask::flag0; - if (!std::is_same::value) + if (static_cast(my_bitmask & MyBitMask::flag0)) + { + TAOX11_TEST_INFO << "Flag my_bitmask correctly set" << std::endl; + } + else + { + TAOX11_TEST_ERROR << "Flag my_bitmask NOT set" << std::endl; + } + if (!std::is_same, uint8_t>::value) { TAOX11_TEST_ERROR << "Type of MyBitMaskBound8 is not uint8_t" << std::endl; } - if (!std::is_same::value) + if (!std::is_same, uint16_t>::value) { TAOX11_TEST_ERROR << "Type of MyBitMaskBound16 is not uint16_t" << std::endl; } + if (!std::is_same, uint32_t>::value) + { + TAOX11_TEST_ERROR << "Type of MyBitMaskBound32 is not uint32_t" << std::endl; + } + if (!std::is_same, uint64_t>::value) + { + TAOX11_TEST_ERROR << "Type of MyBitMaskBound64 is not uint64_t" << std::endl; + } return 0; } diff --git a/tests/idl4/bitmask/test.idl b/tests/idl4/bitmask/test.idl index c80e9e3b..23edba81 100644 --- a/tests/idl4/bitmask/test.idl +++ b/tests/idl4/bitmask/test.idl @@ -25,4 +25,16 @@ bitmask MyBitMaskBound16 { flag16_3 }; -// https://softwareengineering.stackexchange.com/questions/194412/using-scoped-enums-for-bit-flags-in-c +@bit_bound(32) +bitmask MyBitMaskBound32 { + flag32_1, + flag32_2, + flag32_3 +}; + +@bit_bound(64) +bitmask MyBitMaskBound64 { + flag64_1, + flag64_2, + flag64_3 +};