mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	BitField: Make trivially copyable and remove assignment operator
This commit is contained in:
		
							parent
							
								
									f1d1049c4f
								
							
						
					
					
						commit
						6c71858c5c
					
				
					 12 changed files with 56 additions and 60 deletions
				
			
		|  | @ -115,29 +115,24 @@ template<std::size_t position, std::size_t bits, typename T> | ||||||
| struct BitField | struct BitField | ||||||
| { | { | ||||||
| private: | private: | ||||||
|     // This constructor might be considered ambiguous:
 |     // We hide the copy assigment operator here, because the default copy
 | ||||||
|     // Would it initialize the storage or just the bitfield?
 |     // assignment would copy the full storage value, rather than just the bits
 | ||||||
|     // Hence, delete it. Use the assignment operator to set bitfield values!
 |     // relevant to this particular bit field.
 | ||||||
|     BitField(T val) = delete; |     // We don't delete it because we want BitField to be trivially copyable.
 | ||||||
|  |     BitField& operator=(const BitField&) = default; | ||||||
| 
 | 
 | ||||||
| public: | public: | ||||||
|  |     // This constructor and assignment operator might be considered ambiguous:
 | ||||||
|  |     // Would they initialize the storage or just the bitfield?
 | ||||||
|  |     // Hence, delete them. Use the Assign method to set bitfield values!
 | ||||||
|  |     BitField(T val) = delete; | ||||||
|  |     BitField& operator=(T val) = delete; | ||||||
|  | 
 | ||||||
|     // Force default constructor to be created
 |     // Force default constructor to be created
 | ||||||
|     // so that we can use this within unions
 |     // so that we can use this within unions
 | ||||||
|     BitField() = default; |     BitField() = default; | ||||||
| 
 | 
 | ||||||
|     // We explicitly delete the copy assigment operator here, because the
 |     FORCE_INLINE operator T() const { | ||||||
|     // default copy assignment would copy the full storage value, rather than
 |  | ||||||
|     // just the bits relevant to this particular bit field.
 |  | ||||||
|     BitField& operator=(const BitField&) = delete; |  | ||||||
| 
 |  | ||||||
|     FORCE_INLINE BitField& operator=(T val) |  | ||||||
|     { |  | ||||||
|         Assign(val); |  | ||||||
|         return *this; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     FORCE_INLINE operator T() const |  | ||||||
|     { |  | ||||||
|         return Value(); |         return Value(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -145,8 +140,7 @@ public: | ||||||
|         storage = (storage & ~GetMask()) | (((StorageType)value << position) & GetMask()); |         storage = (storage & ~GetMask()) | (((StorageType)value << position) & GetMask()); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     FORCE_INLINE T Value() const |     FORCE_INLINE T Value() const { | ||||||
|     { |  | ||||||
|         if (std::numeric_limits<T>::is_signed) |         if (std::numeric_limits<T>::is_signed) | ||||||
|         { |         { | ||||||
|             std::size_t shift = 8 * sizeof(T)-bits; |             std::size_t shift = 8 * sizeof(T)-bits; | ||||||
|  | @ -159,8 +153,7 @@ public: | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // TODO: we may want to change this to explicit operator bool() if it's bug-free in VS2015
 |     // TODO: we may want to change this to explicit operator bool() if it's bug-free in VS2015
 | ||||||
|     FORCE_INLINE bool ToBool() const |     FORCE_INLINE bool ToBool() const { | ||||||
|     { |  | ||||||
|         return Value() != 0; |         return Value() != 0; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -176,8 +169,7 @@ private: | ||||||
|     // Unsigned version of StorageType
 |     // Unsigned version of StorageType
 | ||||||
|     typedef typename std::make_unsigned<StorageType>::type StorageTypeU; |     typedef typename std::make_unsigned<StorageType>::type StorageTypeU; | ||||||
| 
 | 
 | ||||||
|     FORCE_INLINE StorageType GetMask() const |     FORCE_INLINE StorageType GetMask() const { | ||||||
|     { |  | ||||||
|         return (((StorageTypeU)~0) >> (8 * sizeof(T)-bits)) << position; |         return (((StorageTypeU)~0) >> (8 * sizeof(T)-bits)) << position; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -189,6 +181,10 @@ private: | ||||||
|     static_assert(position < 8 * sizeof(T), "Invalid position"); |     static_assert(position < 8 * sizeof(T), "Invalid position"); | ||||||
|     static_assert(bits <= 8 * sizeof(T), "Invalid number of bits"); |     static_assert(bits <= 8 * sizeof(T), "Invalid number of bits"); | ||||||
|     static_assert(bits > 0, "Invalid number of bits"); |     static_assert(bits > 0, "Invalid number of bits"); | ||||||
|     static_assert(std::is_standard_layout<T>::value, "Invalid base type"); |     static_assert(std::is_pod<T>::value, "Invalid base type"); | ||||||
| }; | }; | ||||||
| #pragma pack() | #pragma pack() | ||||||
|  | 
 | ||||||
|  | #if (__GNUC__ >= 5) || defined __clang__ || defined _MSC_VER | ||||||
|  | static_assert(std::is_trivially_copyable<BitField<0, 1, u32>>::value, "BitField must be trivially copyable"); | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | @ -55,14 +55,14 @@ void EmuWindow::TouchPressed(unsigned framebuffer_x, unsigned framebuffer_y) { | ||||||
|         (framebuffer_layout.bottom_screen.bottom - framebuffer_layout.bottom_screen.top); |         (framebuffer_layout.bottom_screen.bottom - framebuffer_layout.bottom_screen.top); | ||||||
| 
 | 
 | ||||||
|     touch_pressed = true; |     touch_pressed = true; | ||||||
|     pad_state.touch = 1; |     pad_state.touch.Assign(1); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void EmuWindow::TouchReleased() { | void EmuWindow::TouchReleased() { | ||||||
|     touch_pressed = false; |     touch_pressed = false; | ||||||
|     touch_x = 0; |     touch_x = 0; | ||||||
|     touch_y = 0; |     touch_y = 0; | ||||||
|     pad_state.touch = 0; |     pad_state.touch.Assign(0); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void EmuWindow::TouchMoved(unsigned framebuffer_x, unsigned framebuffer_y) { | void EmuWindow::TouchMoved(unsigned framebuffer_x, unsigned framebuffer_y) { | ||||||
|  |  | ||||||
|  | @ -35,7 +35,7 @@ SharedPtr<Process> Process::Create(SharedPtr<CodeSet> code_set) { | ||||||
| 
 | 
 | ||||||
|     process->codeset = std::move(code_set); |     process->codeset = std::move(code_set); | ||||||
|     process->flags.raw = 0; |     process->flags.raw = 0; | ||||||
|     process->flags.memory_region = MemoryRegion::APPLICATION; |     process->flags.memory_region.Assign(MemoryRegion::APPLICATION); | ||||||
|     Memory::InitLegacyAddressSpace(process->vm_manager); |     Memory::InitLegacyAddressSpace(process->vm_manager); | ||||||
| 
 | 
 | ||||||
|     return process; |     return process; | ||||||
|  |  | ||||||
|  | @ -193,10 +193,10 @@ union ResultCode { | ||||||
|     explicit ResultCode(u32 raw) : raw(raw) {} |     explicit ResultCode(u32 raw) : raw(raw) {} | ||||||
|     ResultCode(ErrorDescription description_, ErrorModule module_, |     ResultCode(ErrorDescription description_, ErrorModule module_, | ||||||
|             ErrorSummary summary_, ErrorLevel level_) : raw(0) { |             ErrorSummary summary_, ErrorLevel level_) : raw(0) { | ||||||
|         description = description_; |         description.Assign(description_); | ||||||
|         module = module_; |         module.Assign(module_); | ||||||
|         summary = summary_; |         summary.Assign(summary_); | ||||||
|         level = level_; |         level.Assign(level_); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     ResultCode& operator=(const ResultCode& o) { raw = o.raw; return *this; } |     ResultCode& operator=(const ResultCode& o) { raw = o.raw; return *this; } | ||||||
|  |  | ||||||
|  | @ -293,8 +293,8 @@ ResultCode DeleteConfigNANDSaveFile() { | ||||||
| 
 | 
 | ||||||
| ResultCode UpdateConfigNANDSavegame() { | ResultCode UpdateConfigNANDSavegame() { | ||||||
|     FileSys::Mode mode = {}; |     FileSys::Mode mode = {}; | ||||||
|     mode.write_flag = 1; |     mode.write_flag.Assign(1); | ||||||
|     mode.create_flag = 1; |     mode.create_flag.Assign(1); | ||||||
| 
 | 
 | ||||||
|     FileSys::Path path("config"); |     FileSys::Path path("config"); | ||||||
| 
 | 
 | ||||||
|  | @ -405,7 +405,7 @@ void Init() { | ||||||
| 
 | 
 | ||||||
|     FileSys::Path config_path("config"); |     FileSys::Path config_path("config"); | ||||||
|     FileSys::Mode open_mode = {}; |     FileSys::Mode open_mode = {}; | ||||||
|     open_mode.read_flag = 1; |     open_mode.read_flag.Assign(1); | ||||||
| 
 | 
 | ||||||
|     auto config_result = Service::FS::OpenFileFromArchive(*archive_result, config_path, open_mode); |     auto config_result = Service::FS::OpenFileFromArchive(*archive_result, config_path, open_mode); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -347,7 +347,7 @@ void SignalInterrupt(InterruptId interrupt_id) { | ||||||
|             FrameBufferUpdate* info = GetFrameBufferInfo(thread_id, screen_id); |             FrameBufferUpdate* info = GetFrameBufferInfo(thread_id, screen_id); | ||||||
|             if (info->is_dirty) { |             if (info->is_dirty) { | ||||||
|                 SetBufferSwap(screen_id, info->framebuffer_info[info->index]); |                 SetBufferSwap(screen_id, info->framebuffer_info[info->index]); | ||||||
|                 info->is_dirty = false; |                 info->is_dirty.Assign(false); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | @ -499,7 +499,7 @@ static void SetLcdForceBlack(Service::Interface* self) { | ||||||
| 
 | 
 | ||||||
|     // Since data is already zeroed, there is no need to explicitly set
 |     // Since data is already zeroed, there is no need to explicitly set
 | ||||||
|     // the color to black (all zero).
 |     // the color to black (all zero).
 | ||||||
|     data.is_enabled = enable_black; |     data.is_enabled.Assign(enable_black); | ||||||
| 
 | 
 | ||||||
|     LCD::Write(HW::VADDR_LCD + 4 * LCD_REG_INDEX(color_fill_top), data.raw); // Top LCD
 |     LCD::Write(HW::VADDR_LCD + 4 * LCD_REG_INDEX(color_fill_top), data.raw); // Top LCD
 | ||||||
|     LCD::Write(HW::VADDR_LCD + 4 * LCD_REG_INDEX(color_fill_bottom), data.raw); // Bottom LCD
 |     LCD::Write(HW::VADDR_LCD + 4 * LCD_REG_INDEX(color_fill_bottom), data.raw); // Bottom LCD
 | ||||||
|  | @ -521,7 +521,7 @@ static void TriggerCmdReqQueue(Service::Interface* self) { | ||||||
|             ExecuteCommand(command_buffer->commands[i], thread_id); |             ExecuteCommand(command_buffer->commands[i], thread_id); | ||||||
| 
 | 
 | ||||||
|             // Indicates that command has completed
 |             // Indicates that command has completed
 | ||||||
|             command_buffer->number_commands = command_buffer->number_commands - 1; |             command_buffer->number_commands.Assign(command_buffer->number_commands - 1); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -105,7 +105,7 @@ void Update() { | ||||||
|     bool pressed = false; |     bool pressed = false; | ||||||
| 
 | 
 | ||||||
|     std::tie(touch_entry->x, touch_entry->y, pressed) = VideoCore::g_emu_window->GetTouchState(); |     std::tie(touch_entry->x, touch_entry->y, pressed) = VideoCore::g_emu_window->GetTouchState(); | ||||||
|     touch_entry->valid = pressed ? 1 : 0; |     touch_entry->valid.Assign(pressed ? 1 : 0); | ||||||
| 
 | 
 | ||||||
|     // TODO(bunnei): We're not doing anything with offset 0xA8 + 0x18 of HID SharedMemory, which
 |     // TODO(bunnei): We're not doing anything with offset 0xA8 + 0x18 of HID SharedMemory, which
 | ||||||
|     // supposedly is "Touch-screen entry, which contains the raw coordinate data prior to being
 |     // supposedly is "Touch-screen entry, which contains the raw coordinate data prior to being
 | ||||||
|  |  | ||||||
|  | @ -110,8 +110,8 @@ void Init() { | ||||||
| 
 | 
 | ||||||
|         FileSys::Path gamecoin_path("gamecoin.dat"); |         FileSys::Path gamecoin_path("gamecoin.dat"); | ||||||
|         FileSys::Mode open_mode = {}; |         FileSys::Mode open_mode = {}; | ||||||
|         open_mode.write_flag = 1; |         open_mode.write_flag.Assign(1); | ||||||
|         open_mode.create_flag = 1; |         open_mode.create_flag.Assign(1); | ||||||
|         // Open the file and write the default gamecoin information
 |         // Open the file and write the default gamecoin information
 | ||||||
|         auto gamecoin_result = Service::FS::OpenFileFromArchive(*archive_result, gamecoin_path, open_mode); |         auto gamecoin_result = Service::FS::OpenFileFromArchive(*archive_result, gamecoin_path, open_mode); | ||||||
|         if (gamecoin_result.Succeeded()) { |         if (gamecoin_result.Succeeded()) { | ||||||
|  |  | ||||||
|  | @ -178,17 +178,17 @@ struct CTRPollFD { | ||||||
|         static Events TranslateTo3DS(u32 input_event) { |         static Events TranslateTo3DS(u32 input_event) { | ||||||
|             Events ev = {}; |             Events ev = {}; | ||||||
|             if (input_event & POLLIN) |             if (input_event & POLLIN) | ||||||
|                 ev.pollin = 1; |                 ev.pollin.Assign(1); | ||||||
|             if (input_event & POLLPRI) |             if (input_event & POLLPRI) | ||||||
|                 ev.pollpri = 1; |                 ev.pollpri.Assign(1); | ||||||
|             if (input_event & POLLHUP) |             if (input_event & POLLHUP) | ||||||
|                 ev.pollhup = 1; |                 ev.pollhup.Assign(1); | ||||||
|             if (input_event & POLLERR) |             if (input_event & POLLERR) | ||||||
|                 ev.pollerr = 1; |                 ev.pollerr.Assign(1); | ||||||
|             if (input_event & POLLOUT) |             if (input_event & POLLOUT) | ||||||
|                 ev.pollout = 1; |                 ev.pollout.Assign(1); | ||||||
|             if (input_event & POLLNVAL) |             if (input_event & POLLNVAL) | ||||||
|                 ev.pollnval = 1; |                 ev.pollnval.Assign(1); | ||||||
|             return ev; |             return ev; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -146,8 +146,8 @@ inline void Write(u32 addr, const T data) { | ||||||
| 
 | 
 | ||||||
|             // Reset "trigger" flag and set the "finish" flag
 |             // Reset "trigger" flag and set the "finish" flag
 | ||||||
|             // NOTE: This was confirmed to happen on hardware even if "address_start" is zero.
 |             // NOTE: This was confirmed to happen on hardware even if "address_start" is zero.
 | ||||||
|             config.trigger = 0; |             config.trigger.Assign(0); | ||||||
|             config.finished = 1; |             config.finished.Assign(1); | ||||||
|         } |         } | ||||||
|         break; |         break; | ||||||
|     } |     } | ||||||
|  | @ -444,16 +444,16 @@ void Init() { | ||||||
|     framebuffer_sub.address_left1  = 0x1848F000; |     framebuffer_sub.address_left1  = 0x1848F000; | ||||||
|     framebuffer_sub.address_left2  = 0x184C7800; |     framebuffer_sub.address_left2  = 0x184C7800; | ||||||
| 
 | 
 | ||||||
|     framebuffer_top.width = 240; |     framebuffer_top.width.Assign(240); | ||||||
|     framebuffer_top.height = 400; |     framebuffer_top.height.Assign(400); | ||||||
|     framebuffer_top.stride = 3 * 240; |     framebuffer_top.stride = 3 * 240; | ||||||
|     framebuffer_top.color_format = Regs::PixelFormat::RGB8; |     framebuffer_top.color_format.Assign(Regs::PixelFormat::RGB8); | ||||||
|     framebuffer_top.active_fb = 0; |     framebuffer_top.active_fb = 0; | ||||||
| 
 | 
 | ||||||
|     framebuffer_sub.width = 240; |     framebuffer_sub.width.Assign(240); | ||||||
|     framebuffer_sub.height = 320; |     framebuffer_sub.height.Assign(320); | ||||||
|     framebuffer_sub.stride = 3 * 240; |     framebuffer_sub.stride = 3 * 240; | ||||||
|     framebuffer_sub.color_format = Regs::PixelFormat::RGB8; |     framebuffer_sub.color_format.Assign(Regs::PixelFormat::RGB8); | ||||||
|     framebuffer_sub.active_fb = 0; |     framebuffer_sub.active_fb = 0; | ||||||
| 
 | 
 | ||||||
|     last_skip_frame = false; |     last_skip_frame = false; | ||||||
|  |  | ||||||
|  | @ -429,7 +429,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { | ||||||
|                           uniform.w.ToFloat32()); |                           uniform.w.ToFloat32()); | ||||||
| 
 | 
 | ||||||
|                 // TODO: Verify that this actually modifies the register!
 |                 // TODO: Verify that this actually modifies the register!
 | ||||||
|                 uniform_setup.index = uniform_setup.index + 1; |                 uniform_setup.index.Assign(uniform_setup.index + 1); | ||||||
|             } |             } | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|  | @ -478,7 +478,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { | ||||||
|             ASSERT_MSG(lut_config.index < 256, "lut_config.index exceeded maximum value of 255!"); |             ASSERT_MSG(lut_config.index < 256, "lut_config.index exceeded maximum value of 255!"); | ||||||
| 
 | 
 | ||||||
|             g_state.lighting.luts[lut_config.type][lut_config.index].raw = value; |             g_state.lighting.luts[lut_config.type][lut_config.index].raw = value; | ||||||
|             lut_config.index = lut_config.index + 1; |             lut_config.index.Assign(lut_config.index + 1); | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -201,11 +201,11 @@ void DumpShader(const std::string& filename, const Regs::ShaderConfig& config, c | ||||||
| 
 | 
 | ||||||
|                     if (it == output_info_table.end()) { |                     if (it == output_info_table.end()) { | ||||||
|                         output_info_table.emplace_back(); |                         output_info_table.emplace_back(); | ||||||
|                         output_info_table.back().type = type; |                         output_info_table.back().type.Assign(type); | ||||||
|                         output_info_table.back().component_mask = component_mask; |                         output_info_table.back().component_mask.Assign(component_mask); | ||||||
|                         output_info_table.back().id = i; |                         output_info_table.back().id.Assign(i); | ||||||
|                     } else { |                     } else { | ||||||
|                         it->component_mask = it->component_mask | component_mask; |                         it->component_mask.Assign(it->component_mask | component_mask); | ||||||
|                     } |                     } | ||||||
|                 } catch (const std::out_of_range& ) { |                 } catch (const std::out_of_range& ) { | ||||||
|                     DEBUG_ASSERT_MSG(false, "Unknown output attribute mapping"); |                     DEBUG_ASSERT_MSG(false, "Unknown output attribute mapping"); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue