C ++, рдЗрд╕рдХреЗ рд╕рдЦреНрдд рдЯрд╛рдЗрдкрд┐рдВрдЧ рдХреЗ рдХрд╛рд░рдг, рдХрдВрдкрд╛рдЗрд▓рд░ рд╕реНрдЯреЗрдЬ рдкрд░ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдХреА рдорджрдж рдХрд░ рд╕рдХрддрд╛ рд╣реИред рд╣рдм рдкрд░ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдмрд╣реБрдд рд╕рд╛рд░реЗ рд▓реЗрдЦ рд╣реИрдВ рдЬреЛ рд╡рд░реНрдгрди рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдХреИрд╕реЗ, рдЗрд╕рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рдФрд░ рдпрд╣ рдареАрдХ рд╣реИред рд▓реЗрдХрд┐рди рдореИрдВрдиреЗ рдЬреЛ рдкрдврд╝рд╛ рд╣реИ, рдЙрд╕рдореЗрдВ рдПрдХ рджреЛрд╖ рд╣реИред ++ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдФрд░ CMSIS рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП C рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреА рддреБрд▓рдирд╛ рдХрд░реЗрдВ, рдЬреЛ рдХрд┐ рдорд╛рдЗрдХреНрд░реЛрдХрдВрдЯреНрд░реЛрд▓рд░ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХреА рджреБрдирд┐рдпрд╛ рдореЗрдВ рдкрд░рд┐рдЪрд┐рдд рд╣реИ:
some_stream.set (Direction::to_periph) SOME_STREAM->CR |= DMA_SxCR_DIR_0 .inc_memory() | DMA_SxCR_MINC_Msk .size_memory (DataSize::word16) | DMA_SxCR_MSIZE_0 .size_periph (DataSize::word16) | DMA_SxCR_PSIZE_0 .enable_transfer_complete_interrupt(); | DMA_SxCR_TCIE_Msk;
рдпрд╣ рддреБрд░рдВрдд рд╕реНрдкрд╖реНрдЯ рд╣реИ рдХрд┐ C ++ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдЕрдзрд┐рдХ рдкрдардиреАрдп рд╣реИ, рдФрд░ рдЪреВрдВрдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдлрд╝рдВрдХреНрд╢рди рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкреНрд░рдХрд╛рд░ рдкрд░ рд╣реЛрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдХрд┐рд╕реА рдХреЛ рдЧрд▓рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рд╕реА рджреГрд╖реНрдЯрд┐рдХреЛрдг рдбреЗрдЯрд╛ рдХреА рд╡реИрдзрддрд╛ рдХреА рдЬрд╛рдВрдЪ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдпрд╣ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдХреЗ рд╕рд╛рде рдЖрд░рд╛рдо рдХрд░рддрд╛ рд╣реИред рдПрдХ рдирд┐рдпрдо рдХреЗ рд░реВрдк рдореЗрдВ, рдПрдХ рддреНрд░реБрдЯрд┐ рдХреЗрд╡рд▓ рдбреАрдмрдЧрд┐рдВрдЧ рдХреЗ рджреМрд░рд╛рди рдкрд╣рдЪрд╛рдиреА рдЬрд╛рддреА рд╣реИред рд▓реЗрдХрд┐рди c ++ рдПрдкреНрд░реЛрдЪ рдлреНрд░реА рдирд╣реАрдВ рд╣реИред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдкреНрд░рддреНрдпреЗрдХ рдлрд╝рдВрдХреНрд╢рди рдХреА рд░рдЬрд┐рд╕реНрдЯрд░ рддрдХ рдЕрдкрдиреА рдкрд╣реБрдВрдЪ рд╣реЛрддреА рд╣реИ, рдЬрдмрдХрд┐ C рдореЗрдВ рдорд╛рд╕реНрдХ рдХреЛ рдкрд╣рд▓реЗ рд╕рдВрдХрд▓рди рдХреЗ рд╕реНрддрд░ рдкрд░ рд╕рднреА рдорд╛рдкрджрдВрдбреЛрдВ рд╕реЗ рдПрдХрддреНрд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпреЗ рд╕рднреА рд╕реНрдерд┐рд░рд╛рдВрдХ рд╣реЛрддреЗ рд╣реИрдВ, рдФрд░ рд░рдЬрд┐рд╕реНрдЯрд░ рдореЗрдВ рдПрдХ рд╣реА рдмрд╛рд░ рд▓рд┐рдЦреЗ рдЬрд╛рддреЗ рд╣реИрдВред рдЗрд╕рдХреЗ рдмрд╛рдж, рдореИрдВ рд╡рд░реНрдгрди рдХрд░реВрдВрдЧрд╛ рдХрд┐ рдореИрдВрдиреЗ рдХреЗрд╕ рдПрдХреНрд╕реЗрд╕ рдХреЛ рдиреНрдпреВрдирддрдо рдХрд░рдиреЗ рдХреЗ рд╕рд╛рде ++ рдХреЗ рд╕рд╛рде рдХрд┐рд╕ рдкреНрд░рдХрд╛рд░ рдХреА рд╕реБрд░рдХреНрд╖рд╛ рдХреЛ рд╕рдВрдпреЛрдЬрд┐рдд рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд┐рдпрд╛ рд╣реИред рдЖрдк рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐ рдпрд╣ рдЬрд┐рддрдирд╛ рд╕рд░рд▓ рд╣реИ, рдЙрд╕рд╕реЗ рдХрд╣реАрдВ рдЬреНрдпрд╛рджрд╛ рд╕рд░рд▓ рд╣реИред
рдкрд╣рд▓реЗ рдореИрдВ рдПрдХ рдЙрджрд╛рд╣рд░рдг рджреВрдВрдЧрд╛ рдХрд┐ рдореИрдВ рдЗрд╕реЗ рдХреИрд╕реЗ рджреЗрдЦрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред рдпрд╣ рд╡рд╛рдВрдЫрдиреАрдп рд╣реИ рдХрд┐ рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рдкрд░рд┐рдЪрд┐рдд C ++ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ рдмрд╣реБрдд рднрд┐рдиреНрди рдирд╣реАрдВ рд╣реИред
some_stream.set( dma_stream::direction::to_periph , dma_stream::inc_memory , dma_stream::memory_size::byte16 , dma_stream::periph_size::byte16 , dma_stream::transfer_complete_interrupt::enable );
рд╕реЗрдЯ рд╡рд┐рдзрд┐ рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдПрдХ рдЕрд▓рдЧ рдкреНрд░рдХрд╛рд░ рд╣реИ рдЬрд┐рд╕рдХреЗ рджреНрд╡рд╛рд░рд╛ рдЖрдк рд╕рдордЭ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдЖрдк рдХрд┐рд╕ рд░рдЬрд┐рд╕реНрдЯрд░ рдореЗрдВ рдореВрд▓реНрдп рд▓рд┐рдЦрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рд╕рдВрдХрд▓рди рдХреЗ рджреМрд░рд╛рди рдЖрдк рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рддрдХ рдкрд╣реБрдВрдЪ рдХреЛ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╡рд┐рдзрд┐ рдкрд░рд┐рд╡рд░реНрддрдирд╢реАрд▓ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдХрд┐рд╕реА рднреА рддрд░реНрдХ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдПрдХ рдЬрд╛рдВрдЪ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдП рдХрд┐ рд╕рднреА рддрд░реНрдХ рдЗрд╕ рдкрд░рд┐рдзрд┐ рдХреЗ рд╣реИрдВред
рдкрд╣рд▓реЗ рдпрд╣ рдХрд╛рд░реНрдп рдореЗрд░реЗ рд▓рд┐рдП рдЬрдЯрд┐рд▓ рд▓рдЧ рд░рд╣рд╛ рдерд╛, рдЬрдм рддрдХ рдХрд┐ рдореИрдВ рдореВрд▓реНрдп-рдЖрдзрд╛рд░рд┐рдд рдореЗрдЯрд╛рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЗрд╕ рд╡реАрдбрд┐рдпреЛ рдореЗрдВ рдирд╣реАрдВ рдЖрдпрд╛ рдерд╛ред рдореЗрдЯрд╛рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдпрд╣ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдЖрдкрдХреЛ рд╕рд╛рдорд╛рдиреНрдпреАрдХреГрдд рдПрд▓реНрдЧреЛрд░рд┐рджрдо рд▓рд┐рдЦрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдЬреИрд╕реЗ рдХрд┐ рдпрд╣ рд╕рд╛рдорд╛рдиреНрдп рдкреНрд▓рд╕ рдХреЛрдб рдерд╛ред рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдореИрдВ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЗрд╡рд▓ рд╕рдмрд╕реЗ рдЖрд╡рд╢реНрдпрдХ рд╡реАрдбрд┐рдпреЛ рджреВрдВрдЧрд╛, рдЗрд╕рдореЗрдВ рдмрд╣реБрдд рдЕрдзрд┐рдХ рд╕рд╛рдорд╛рдиреНрдпреАрдХреГрдд рдПрд▓реНрдЧреЛрд░рд┐рджрдо рд╣реИрдВред
рдореИрдВ рд╕рдорд╕реНрдпрд╛ рдХреЛ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкрд░рд┐рдзрд┐ рдХреЗ рд▓рд┐рдП рдирд╣реАрдВ, рдмрд▓реНрдХрд┐ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╣рд▓ рдХрд░реВрдВрдЧрд╛ред рдЗрд╕рд▓рд┐рдП, рдХрдИ рд░рдЬрд┐рд╕реНрдЯрд░ рдХреНрд╖реЗрддреНрд░ рд╣реИрдВ, рдореИрдВ рдЙрдиреНрд╣реЗрдВ рд╕рд╢рд░реНрдд рд░реВрдк рд╕реЗ рд╕рд╢рд░реНрдд рд░реВрдк рд╕реЗ рд▓рд┐рдЦреВрдВрдЧрд╛ред
enum struct Enum1 { _0, _1, _2, _3 }; enum struct Enum2 { _0, _1, _2, _3 }; enum struct Enum3 { _0, _1, _2, _3, _4 }; enum struct Enum4 { _0, _1, _2, _3 };
рдкрд╣рд▓реЗ рддреАрди рдПрдХ рдкрд░рд┐рдзрд┐ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реЛрдВрдЧреЗ, рджреВрд╕рд░реЗ рд╕реЗ рдЪреМрдереЗред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдпрджрд┐ рдЖрдк рдкрд╣рд▓реА рдкрд░рд┐рдзрд┐ рдХреА рд╡рд┐рдзрд┐ рдореЗрдВ рдЪреМрдереЗ рдЧрдгрди рдХрд╛ рдорд╛рди рджрд░реНрдЬ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдПрдХ рд╕рдВрдХрд▓рди рддреНрд░реБрдЯрд┐ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдП, рдЕрдзрд┐рдорд╛рдирддрдГ рд╕рдордЭрдиреЗ рдпреЛрдЧреНрдпред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдкрд╣рд▓реЗ 2 рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ рдПрдХ рд░рдЬрд┐рд╕реНрдЯрд░ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реЛрдВрдЧреЗ, рджреВрд╕рд░реЗ рд╕реЗ рджреВрд╕рд░реЗ рдореЗрдВред
рдЪреВрдБрдХрд┐ рдЧрдгрдирд╛ рдХреЗ рдорд╛рди рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдореВрд▓реНрдпреЛрдВ рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдЕрдкрдиреЗ рдЖрдк рдореЗрдВ рдХреБрдЫ рднреА рд╕рдВрдЧреНрд░рд╣реАрдд рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рдкреНрд░рдХрд╛рд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЬреЛ рд╕реНрдЯреЛрд░ рдХрд░реЗрдЧрд╛, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрд╣ рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд░рдЬрд┐рд╕реНрдЯрд░ рдХреЗ рдХрд┐рд╕ рднрд╛рдЧ рдореЗрдВ рдПрдХ рдореБрдЦреМрдЯрд╛ рд▓рд┐рдЦрд╛ рдЬрд╛рдПрдЧрд╛ред
struct Enum1_traits { static constexpr std::size_t mask = 0b00111; }; struct Enum2_traits { static constexpr std::size_t mask = 0b11000; }; struct Enum3_traits { static constexpr std::size_t mask = 0b00111; }; struct Enum4_traits { static constexpr std::size_t mask = 0b00111; };
рдпрд╣ рдЗрди 2 рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдирд╛ рд╣реБрдЖ рд╣реИред рдпрд╣рд╛рдВ рдЪрд┐рдк 20 рдорд╛рдирдХреЛрдВ рдХреЗ рд▓рд┐рдП рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЙрдкрдпреЛрдЧреА рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдХрд╛рдлреА рддреБрдЪреНрдЫ рд╣реИ рдФрд░ рдЖрдк рдЗрд╕реЗ рд╕реНрд╡рдпрдВ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
template <class T> struct type_identity { using type = T; };
рд▓рдмреНрдмреЛрд▓реБрдЖрдм рдпрд╣ рд╣реИ рдХрд┐ рдЖрдк рдХрд┐рд╕реА рднреА рдкреНрд░рдХрд╛рд░ рд╕реЗ рдПрдХ рдореВрд▓реНрдп рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕реЗ рдПрдХ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдкрд╛рд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ рдореВрд▓реНрдп-рдЖрдзрд╛рд░рд┐рдд рдореЗрдЯрд╛рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рдореБрдЦреНрдп рдИрдВрдЯ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдЖрдкрдХреЛ рдорд╛рдиреЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЯрд╛рдЗрдк рдЬрд╛рдирдХрд╛рд░реА рдХреЛ рдкрд╛рд╕ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рдиреА рдЪрд╛рд╣рд┐рдП, рди рдХрд┐ рдЯреЗрдореНрдкрд▓реЗрдЯ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВред рдпрд╣рд╛рдБ рдореИрдВрдиреЗ рдПрдХ рдореИрдХреНрд░реЛ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВ c ++ рдореЗрдВ рдЙрдирдХрд╛ рд╡рд┐рд░реЛрдзреА рд╣реВрдВред рд▓реЗрдХрд┐рди рд╡рд╣ рдЖрдЧреЗ рдХрдо рд▓рд┐рдЦрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдЕрдЧрд▓рд╛, рдореИрдВ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдФрд░ рдПрдХ рдЕрдиреНрдп рдореИрдХреНрд░реЛ рдХреЛ рд▓рд┐рдВрдХрд┐рдВрдЧ рдПрдиреНрдпреВрдорд░реЗрд╢рди рдФрд░ рдЙрд╕рдХреЗ рдЧреБрдг рджреЗрдЧрд╛ рдЬреЛ рдХреЙрдкреА рдкреЗрд╕реНрдЯ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЛ рдХрдо рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред
constexpr auto traits(type_identity<Enum1>) { return type_identity<Enum1_traits>{}; } #define MAKE_TRAITS_WITH_MASK(enum, mask_) struct enum##_traits { \ static constexpr std::size_t mask = mask_; \ }; \ constexpr auto traits(type_identity<enum>) { \ return type_identity<enum##_traits>{}; \ }
рд╕рдВрдмрдВрдзрд┐рдд рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдХреЗ рд╕рд╛рде рдЦреЗрддреЛрдВ рдХреЛ рдЬреЛрдбрд╝рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдореИрдВрдиреЗ рд╡рд┐рд░рд╛рд╕рдд рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕рдВрдмрдВрдз рдЪреБрдирд╛, рдХреНрдпреЛрдВрдХрд┐ рдорд╛рдирдХ рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдореЗрдЯрд╛рдлрдВрдХреНрд╢рди std::is_base_of
, рдЬреЛ рдЖрдкрдХреЛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╕рд╛рдорд╛рдиреНрдпреАрдХреГрдд рд░реВрдк рдореЗрдВ рдлрд╝реАрд▓реНрдб рдФрд░ рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдХреЗ рдмреАрдЪ рдХреЗ рд░рд┐рд╢реНрддреЗ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛ред рдЖрдк рдЧрдгрдирд╛ рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдирд╣реАрдВ рд▓реЗ рд╕рдХрддреЗ, рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ рдЙрдирдХреЗ рдЧреБрдгреЛрдВ рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓реА рд╣реИред
struct Register1 : Enum1_traits, Enum2_traits { static constexpr std::size_t offset = 0x0; };
рдкрддрд╛ рдЬрд╣рд╛рдВ рд░рдЬрд┐рд╕реНрдЯрд░ рд╕реНрдерд┐рдд рд╣реИ, рдкрд░рд┐рдзрд┐ рдХреА рд╢реБрд░реБрдЖрдд рд╕реЗ рдПрдХ рдСрдлрд╕реЗрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдкрд░рд┐рдзрд┐ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдореВрд▓реНрдп-рдЖрдзрд╛рд░рд┐рдд рдореЗрдЯрд╛рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдореЗрдВ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреА рд╕реВрдЪреА рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдпрд╣ рдПрдХ рдХрд╛рдлреА рд╕рд░рд▓ рд╕рдВрд░рдЪрдирд╛ рд╣реИ рдЬреЛ рдЖрдкрдХреЛ рдХрдИ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдмрдЪрд╛рдиреЗ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдореВрд▓реНрдп рд╕реЗ рдкрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдХреБрдЫ рдкреНрд░рдХрд╛рд░ рдХреА рддрд░рд╣, рд▓реЗрдХрд┐рди рдХреБрдЫ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдПред
template <class...Ts> struct type_pack{}; using empty_pack = type_pack<>;
рдЖрдк рдЗрд╕ рд╕реВрдЪреА рдХреЗ рд▓рд┐рдП рдХрдИ рдмрд╛рдзрд╛ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЙрдирдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкреНрд░рд╕рд┐рджреНрдз рдЕрд▓реЗрдХреНрдЬреЗрдВрдбреНрд░реЗрд╕реНрдХреБ рдкреНрд░рдХрд╛рд░ рдХреА рд╕реВрдЪрд┐рдпреЛрдВ (рд▓реЛрдХреА рдкреБрд╕реНрддрдХрд╛рд▓рдп) рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рд╕рдордЭрдирд╛ рдмрд╣реБрдд рдЖрд╕рд╛рди рд╣реИред рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЙрджрд╛рд╣рд░рдг рд╣реИрдВред
рдкрд░рд┐рдзрд┐ рдХреА рджреВрд╕рд░реА рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╕рдВрдкрддреНрддрд┐ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкрддреЗ (рдорд╛рдЗрдХреНрд░реЛрдХрдВрдЯреНрд░реЛрд▓рд░) рдкрд░ рджреЛрдиреЛрдВ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдФрд░ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рд▓рд┐рдП рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рдкрддреЗ рдХреЛ рдкрд╛рд╕ рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдПред рдЗрд╕рд▓рд┐рдП, рдкрд░рд┐рдзрд┐ рдХреА рд╕рдВрд░рдЪрдирд╛ рдмреЙрдпрд▓рд░рдкреНрд▓реЗрдЯ рд╣реЛрдЧреА, рдФрд░ рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рдкреНрд░рдХрд╛рд░ рд▓реЗрдЧрд╛ рдЬреЛ рдореВрд▓реНрдп рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдкрд░рд┐рдзрд┐ рдХреЗ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкрддреЗ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░реЗрдЧрд╛ред рдЯреЗрдореНрдкрд▓реЗрдЯ рдкреИрд░рд╛рдореАрдЯрд░ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рд╕реЗ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдЦреИрд░, рд╕реЗрдЯ рд╡рд┐рдзрд┐, рдЬрд┐рд╕рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдкрд╣рд▓реЗ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред
template<class Address> struct Periph1 { Periph1(Address) {} static constexpr auto registers = type_pack<Register1, Register2>{}; template<class...Ts> static constexpr void set(Ts...args) { ::set(registers, Address::value, args...); } };
рд╕рднреА рдЬреЛ рд╕реЗрдЯ рд╡рд┐рдзрд┐ рдХрд░рддрд╛ рд╣реИ рд╡рд╣ рдПрдХ рдирд┐рд╢реБрд▓реНрдХ рдлрд╝рдВрдХреНрд╢рди рдХрд╣рд▓рд╛рддрд╛ рд╣реИ, рдЗрд╕рдореЗрдВ рд╕рд╛рдорд╛рдиреНрдпреАрдХреГрдд рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╕рднреА рдЬрд╛рдирдХрд╛рд░реА рдЧреБрдЬрд░рддреА рд╣реИред
рдореИрдВ рдЙрди рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рдЙрджрд╛рд╣рд░рдг рджреВрдВрдЧрд╛ рдЬреЛ рдкрд░рд┐рдзрд┐ рдХреЛ рдПрдХ рдкрддрд╛ рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВред
рд╕рд╛рдорд╛рдиреНрдпреАрдХреГрдд рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЗ рд▓рд┐рдП рд╕рднреА рдЬрд╛рдирдХрд╛рд░реА рддреИрдпрд╛рд░ рдХреА рдЬрд╛рддреА рд╣реИ, рдпрд╣ рдЗрд╕реЗ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдиреА рд╣реБрдИ рд╣реИред рдореИрдВ рдЗрд╕ рдлрдВрдХреНрд╢рди рдХрд╛ рдЯреЗрдХреНрд╕реНрдЯ рджреВрдВрдЧрд╛ред
template<class...Registers, class...Args> constexpr void set(type_pack<Registers...> registers, std::size_t address, Args...args) {
рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЬреЛ рддрд░реНрдХреЛрдВ (рд╡рд┐рд╢рд┐рд╖реНрдЯ рд░рдЬрд┐рд╕реНрдЯрд░ рдлрд╝реАрд▓реНрдб) рдХреЛ type_pack
рдореЗрдВ type_pack
рд╣реИ, рдмрд╣реБрдд рддреБрдЪреНрдЫ рд╣реИред рдЖрдкрдХреЛ рдпрд╛рдж рджрд┐рд▓рд╛ рджреВрдВ рдХрд┐ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдЯрд╛рдЗрдк рд╕реВрдЪреА рдХреА рджреАрд░реНрдШрд╡реГрддреНрдд рдХреЛ рдЕрд▓реНрдкрд╡рд┐рд░рд╛рдо рджреНрд╡рд╛рд░рд╛ рдЕрд▓рдЧ рдХрд┐рдП рдЧрдП рдкреНрд░рдХрд╛рд░реЛрдВ рдХреА рд╕реВрдЪреА рдмрддрд╛рддреА рд╣реИред
template <class...Ts> constexpr auto make_type_pack(type_identity<Ts>...) { return type_pack<Ts...>{}; }
рдпрд╣ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рд╕рднреА рддрд░реНрдХ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИрдВ, рдФрд░ рдЗрд╕рд▓рд┐рдП рд╡рд┐рд╢рд┐рд╖реНрдЯ рдмрд╛рд╣реНрдп рдЙрдкрдХрд░рдгреЛрдВ рдХреЗ рд▓рд┐рдП, рдпрд╣ all_of рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдорд╛рдирдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЗ рд╕рд╛рде рд╕рдорд╛рдирддрд╛ рд╕реЗ, рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдЗрдирдкреБрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рдФрд░ рдПрдХ рд╡рд┐рдзреЗрдп рдлрд╝рдВрдХреНрд╢рди рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИред рд╣рдо рдлрдВрдХреНрд╢рди рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рд▓реИрдореНрдмреНрдбрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред
template <class F, class...Ts> constexpr auto all_of(type_pack<Ts...>, F f) { return (f(type_identity<Ts>{}) and ...); }
рдпрд╣рд╛рдВ, рдкрд╣рд▓реА рдмрд╛рд░, 17 рдорд╛рдирдХ рдХреА рдПрдХ рд╕реНрдХреИрди рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рд▓рд╛рдЧреВ рд╣реЛрддреА рд╣реИред рдпрд╣ рд╡рд╣ рдирд╡рд╛рдЪрд╛рд░ рд╣реИ рдЬрд┐рд╕рдиреЗ рдореЗрдЯрд╛рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХреЗ рд╢реМрдХреАрди рд▓реЛрдЧреЛрдВ рдХреЗ рдЬреАрд╡рди рдХреЛ рд╕рд░рд▓ рдмрдирд╛рдпрд╛ рд╣реИред рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдлрд╝рдВрдХреНрд╢рди рдЪ рдХреЛ рд╕реВрдЪреА Ts рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рдХрд╛рд░ рдкрд░ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕реЗ type_identity
рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рдХреЙрд▓ рдХрд╛ рдкрд░рд┐рдгрд╛рдо I рджреНрд╡рд╛рд░рд╛ рдПрдХрддреНрд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
static_assert
рдЕрдВрджрд░, рдпрд╣ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред args_traits
рд▓рд┐рдкрдЯреЗ type_identity
рдХреЛ рдмрд╛рд░реА-рдмрд╛рд░реА рд╕реЗ type_identity
рдЬрд╛рддрд╛ рд╣реИред рд▓реИрдореНрдмреНрдбрд╛ рдХреЗ рдЕрдВрджрд░, рдорд╛рдирдХ рдореЗрдЯрд╛рдлрдВрдХреНрд╢рди std :: is_base_of рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЪреВрдВрдХрд┐ рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ рд░рдЬрд┐рд╕реНрдЯрд░ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ, OR рд▓реЙрдЬрд┐рдХ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдХреЗ рд▓рд┐рдП рдЗрд╕реЗ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реНрдХреИрди рдПрдХреНрд╕рдкреНрд░реЗрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдирддреАрдЬрддрди, рдЕрдЧрд░ рдХрдо рд╕реЗ рдХрдо рдПрдХ рддрд░реНрдХ рд╣реИ, рдЬрд┐рд╕рдХреЗ рдЧреБрдг рдХрдо рд╕реЗ рдХрдо рдПрдХ рд░рдЬрд┐рд╕реНрдЯрд░ рдХреЗ рд▓рд┐рдП рдмреБрдирд┐рдпрд╛рджреА рдирд╣реАрдВ рд╣реИрдВ, рддреЛ static assert
рдХрд╛рдо рдХрд░реЗрдЧрд╛ рдФрд░ рдПрдХ рд╕реНрдкрд╖реНрдЯ рддреНрд░реБрдЯрд┐ рд╕рдВрджреЗрд╢ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗрдЧрд╛ред рдпрд╣ рд╕рдордЭрдирд╛ рдЖрд╕рд╛рди рд╣реИ рдХрд┐ рддреНрд░реБрдЯрд┐ рдХрд┐рд╕ рдЬрдЧрд╣ рд╕реЗ рд╣реИ (рдпрд╣ set
рд╡рд┐рдзрд┐ рдХреЗ рд▓рд┐рдП рдЧрд▓рдд рддрд░реНрдХ рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рд╣реИ) рдФрд░ рдЗрд╕реЗ рдареАрдХ рдХрд░реЗрдВред
any_of
рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди, рдЬрд┐рд╕рдХреА рдмрд╛рдж рдореЗрдВ рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА, рдмрд╣реБрдд рд╕рдорд╛рди рд╣реИ:
template <class F, class...Ts> constexpr auto any_of(type_pack<Ts...>, F f) { return (f(type_identity<Ts>{}) or ...); }
рд╕рд╛рдорд╛рдиреНрдпреАрдХреГрдд рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХрд╛ рдЕрдЧрд▓рд╛ рдХрд╛рд░реНрдп рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдирд╛ рд╣реИ рдХрд┐ рдХрд┐рди рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдХреЛ рд▓рд┐рдЦрдирд╛ рд╣реЛрдЧрд╛ред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдХреА рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╕реВрдЪреА рдХреЛ рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд░реЗрдВ рдФрд░ рдХреЗрд╡рд▓ рдЙрдиреНрд╣реАрдВ рдХреЛ рдЫреЛрдбрд╝реЗрдВ рдЬрд┐рдирдореЗрдВ рд╣рдорд╛рд░реЗ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рддрд░реНрдХ рд╣реИрдВред рд╣рдореЗрдВ рдПрдХ filter
рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬреЛ рдореВрд▓ type_pack
рд▓реЗрддрд╛ рд╣реИ, рд╕реВрдЪреА рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓рд┐рдП рд╡рд┐рдзреЗрдп рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдпрджрд┐ рдпрд╣ рд╕рд╣реА рд╣реИ рддреЛ рдирдИ рд╕реВрдЪреА рдореЗрдВ рдЬреЛрдбрд╝рддрд╛ рд╣реИред
template <class F, class...Ts> constexpr auto filter(type_pack<Ts...>, F f) { auto filter_one = [](auto v, auto f) { using T = typename decltype(v)::type; if constexpr (f(v)) return type_pack<T>{}; else return empty_pack{}; }; return (empty_pack{} + ... + filter_one(type_identity<Ts>{}, f)); }
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдПрдХ рд▓реИрдореНрдмреНрдбрд╛ рдХрд╛ рд╡рд░реНрдгрди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬреЛ рдПрдХ рдкреНрд░рдХрд╛рд░ рдкрд░ рдПрдХ рд╡рд┐рдзреЗрдп рдХрд╛ рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИ рдФрд░ type_pack
рд╕рд╛рде type_pack
рд▓реМрдЯрд╛рддрд╛ рд╣реИ рдпрджрд┐ рд╡рд┐рдзреЗрдп рд╕рд╣реА рд▓реМрдЯрд╛ рд╣реИ, рдпрд╛ рдЦрд╛рд▓реА type_pack
рдпрджрд┐ рд╡рд┐рдзреЗрдп false
рд▓реМрдЯрд╛ false
ред рдкрд┐рдЫрд▓реЗ рдкреНрд▓рд╕рд╕ рдХреА рдПрдХ рдФрд░ рдирдИ рд╡рд┐рд╢реЗрд╖рддрд╛ рдпрд╣рд╛рдВ рдорджрдж рдХрд░рддреА рд╣реИ - рдЕрдЧрд░ рдХреЛрдИред рдЗрд╕рдХрд╛ рд╕рд╛рд░ рдпрд╣ рд╣реИ рдХрд┐ рдкрд░рд┐рдгрд╛рдореА рдХреЛрдб рдореЗрдВ рдХреЗрд╡рд▓ рдПрдХ рд╣реИ рдпрджрд┐ рд╢рд╛рдЦрд╛, рджреВрд╕рд░рд╛ рдлреЗрдВрдХрд╛ рдЧрдпрд╛ рд╣реИред рдФрд░ рдЪреВрдВрдХрд┐ рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рд╡рд┐рднрд┐рдиреНрди рд╢рд╛рдЦрд╛рдУрдВ рдореЗрдВ рд▓реМрдЯрддреЗ рд╣реИрдВ, рдмрд┐рдирд╛ рдХрд┐рд╕реА рдмрд╛рдзрд╛ рдХреЗ рдПрдХ рд╕рдВрдХрд▓рди рддреНрд░реБрдЯрд┐ рд╣реЛрдЧреАред рд╕реВрдЪреА рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓рд┐рдП рдЗрд╕ рд▓реИрдореНрдмреНрдбрд╛ рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХрд╛ рдкрд░рд┐рдгрд╛рдо рдПрдХ рдкрд░рд┐рдгрд╛рдореА type_pack
, рдлрд┐рд░ рд╕реЗ type_pack
рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред type_pack
рд▓рд┐рдП рдЕрддрд┐рд░рд┐рдХреНрдд рдСрдкрд░реЗрдЯрд░ рдХрд╛ рдкрд░реНрдпрд╛рдкреНрдд рдЕрдзрд┐рднрд╛рд░ рдирд╣реАрдВ рд╣реИред рдЗрд╕рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рднреА рдХрд╛рдлреА рд╕рд░рд▓ рд╣реИ:
template <class...Ts, class...Us> constexpr auto operator+ (type_pack<Ts...>, type_pack<Us...>) { return type_pack<Ts..., Us...>{}; }
рдирдП рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЛ рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдХреА рд╕реВрдЪреА рдкрд░ рд▓рд╛рдЧреВ рдХрд░рдирд╛, рдХреЗрд╡рд▓ рдЙрди рд▓реЛрдЧреЛрдВ рдХреЛ, рдЬрд┐рдиреНрд╣реЗрдВ рд╣рд╕реНрддрд╛рдВрддрд░рд┐рдд рддрд░реНрдХ рд▓рд┐рдЦреЗ рдЬрд╛рдиреЗ рдЪрд╛рд╣рд┐рдП, рдирдИ рд╕реВрдЪреА рдореЗрдВ рдЫреЛрдбрд╝ рджрд┐рдП рдЧрдП рд╣реИрдВред
рдЕрдЧрд▓реЗ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреА рдЬрд░реВрд░рдд рд╣реЛрдЧреА рдХрд┐ foreach
ред рдпрд╣ рдмрд╕ рд╕реВрдЪреА рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓рд┐рдП рдПрдХ рдлрд╝рдВрдХреНрд╢рди рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕реЗ type_identity
рдореЗрдВ type_identity
ред рдпрд╣рд╛рдВ, рд╕реНрдХреИрди рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдореЗрдВ рдПрдХ рдЕрд▓реНрдкрд╡рд┐рд░рд╛рдо рдСрдкрд░реЗрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рдЕрд▓реНрдкрд╡рд┐рд░рд╛рдо рджреНрд╡рд╛рд░рд╛ рд╡рд░реНрдгрд┐рдд рд╕рднреА рдХреНрд░рд┐рдпрд╛ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЕрдВрддрд┐рдо рдХреНрд░рд┐рдпрд╛ рдХрд╛ рдкрд░рд┐рдгрд╛рдо рджреЗрддрд╛ рд╣реИред
template <class F, class...Ts> constexpr void foreach(type_pack<Ts...>, F f) { (f(type_identity<Ts>{}), ...); }
рдлрд╝рдВрдХреНрд╢рди рдЖрдкрдХреЛ рдЙрди рд╕рднреА рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдореЗрдВ рдЬрд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдЬрд╣рд╛рдВ рдЖрдк рд▓рд┐рдЦрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рд▓реИрдореНрдмреНрдбрд╛ рд░рдЬрд┐рд╕реНрдЯрд░ рдореЗрдВ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдореВрд▓реНрдп рдХреА рдЧрдгрдирд╛ рдХрд░рддрд╛ рд╣реИ, рдЙрд╕ рдкрддреЗ рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИ рдЬрд╣рд╛рдВ рдЖрдк рд▓рд┐рдЦрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рдФрд░ рд╕реАрдзреЗ рд░рдЬрд┐рд╕реНрдЯрд░ рдкрд░ рд▓рд┐рдЦрддреЗ рд╣реИрдВред
рдПрдХ рд░рдЬрд┐рд╕реНрдЯрд░ рдХреЗ рдореВрд▓реНрдп рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдкреНрд░рддреНрдпреЗрдХ рддрд░реНрдХ рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рдпрд╣ рд░рдЬрд┐рд╕реНрдЯрд░ рд╣реИ, рдХреЗ рдореВрд▓реНрдп рдХреА рдЧрдгрдирд╛ рдХреА рдЬрд╛рддреА рд╣реИ, рдФрд░ рдкрд░рд┐рдгрд╛рдо OR рджреНрд╡рд╛рд░рд╛ рд╕рдВрдпреБрдХреНрдд рд╣реЛрддрд╛ рд╣реИред
template<class Register, class...Args> constexpr std::size_t register_value(type_identity<Register> reg, Args...args) { return (arg_value(reg, args) | ...); }
рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХреНрд╖реЗрддреНрд░ рдХреЗ рд▓рд┐рдП рдПрдХ рдореВрд▓реНрдп рдХреА рдЧрдгрдирд╛ рдХреЗрд╡рд▓ рдЙрди рддрд░реНрдХреЛрдВ рдХреЗ рд▓рд┐рдП рдХреА рдЬрд╛рдиреА рдЪрд╛рд╣рд┐рдП рдЬрд┐рдирд╕реЗ рдпрд╣ рд░рдЬрд┐рд╕реНрдЯрд░ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓рд╛ рд╣реИред рддрд░реНрдХ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЗрд╕рдХреА рд╕рдВрдкрддреНрддрд┐ рд╕реЗ рдПрдХ рдореБрдЦреМрдЯрд╛ рдирд┐рдХрд╛рд▓рддреЗ рд╣реИрдВ, рдореБрдЦреМрдЯрд╛ рд╕реЗ рд░рдЬрд┐рд╕реНрдЯрд░ рдХреЗ рдЕрдВрджрд░ рдореВрд▓реНрдп рдХреА рдСрдлрд╕реЗрдЯ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВред
template<class Register, class Arg> constexpr std::size_t arg_value(type_identity<Register>, Arg arg) { constexpr auto arg_traits = traits(type_identity<Arg>{});
рдорд╛рд╕реНрдХ рдХреЛ рд╕реНрд╡рдпрдВ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдк рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдореИрдВрдиреЗ рдореМрдЬреВрджрд╛ рдмрд┐рд▓рд┐рди рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рд╣реИред
constexpr auto shift(std::size_t mask) { return __builtin_ffs(mask) - 1; }
рдЕрдВрддрд┐рдо рдлрд╝рдВрдХреНрд╢рди рдЬреЛ рдХрд┐рд╕реА рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкрддреЗ рдкрд░ рдорд╛рди рд▓рд┐рдЦрддрд╛ рд╣реИ, рд╡рд╣ рд░рд╣рддрд╛ рд╣реИред
inline void write(std::size_t address, std::size_t v) { *reinterpret_cast<std::size_t*>(address) |= v; }
рдХрд╛рд░реНрдп рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдПрдХ рдЫреЛрдЯрд╛ рдкрд░реАрдХреНрд╖рдг рд▓рд┐рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИ:
рдпрд╣рд╛рдБ рд▓рд┐рдЦреА рдЧрдИ рд╣рд░ рдЪреАрдЬрд╝ рдХреЛ рдПрдХ рд╕рд╛рде рдЬреЛрдбрд╝рдХрд░ рдЧреЙрдбрдмреЛрд▓реНрдЯ рдореЗрдВ рд╕рдВрдХрд▓рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ ред рд╡рд╣рд╛рдБ рдХреЛрдИ рднреА рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рд╕рд╛рде рдкреНрд░рдпреЛрдЧ рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдпрд╣ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рд▓рдХреНрд╖реНрдп рдкреВрд░рд╛ рд╣реЛ рдЧрдпрд╛ рд╣реИ: рдХреЛрдИ рдЕрдирд╛рд╡рд╢реНрдпрдХ рдореЗрдореЛрд░реА рдПрдХреНрд╕реЗрд╕ рдирд╣реАрдВ рд╣реИред рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдореЗрдВ рд▓рд┐рдЦреЗ рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдореВрд▓реНрдп рдХреА рдЧрдгрдирд╛ рд╕рдВрдХрд▓рди рдЪрд░рдг рдореЗрдВ рдХреА рдЬрд╛рддреА рд╣реИ:
main: mov QWORD PTR Address::value[rip], OFFSET FLAT:arr or QWORD PTR arr[rip], 25 or QWORD PTR arr[rip+8], 4 mov eax, 0 ret
рдкреБрдирд╢реНрдЪ:
рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рднреА рдХреЛ рдзрдиреНрдпрд╡рд╛рдж, рдЙрдирдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, рдореИрдВрдиреЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЛ рдереЛрдбрд╝рд╛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд┐рдпрд╛ред рдЖрдк рдпрд╣рд╛рдВ рдирдпрд╛ рд╡рд┐рдХрд▓реНрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ ред
- рд╣рдЯрд╛рдП рдЧрдП рд╕рд╣рд╛рдпрдХреЛрдВ рдХреЗ рдкреНрд░рдХрд╛рд░ * _traits, рдорд╛рд╕реНрдХ рдХреЛ рд╕реАрдзреЗ рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ рдореЗрдВ рдмрдЪрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
enum struct Enum1 { _0, _1, _2, _3, mask = 0b00111 };
- рддрд░реНрдХреЛрдВ рдХреЗ рд╕рд╛рде рд░рдЬрд┐рд╕реНрдЯрд░ рдХрдиреЗрдХреНрд╢рди рдЕрдм рд╡рд┐рд░рд╛рд╕рдд рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЕрдм рдпрд╣ рдПрдХ рд╕реНрдерд┐рд░ рд░рдЬрд┐рд╕реНрдЯрд░ рдлрд╝реАрд▓реНрдб рд╣реИ
static constexpr auto params = type_pack<Enum1, Enum2>{};
- рдЪреВрдБрдХрд┐ рдХрдиреЗрдХреНрд╢рди рдЕрдм рд╡рдВрд╢рд╛рдиреБрдХреНрд░рдо рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореБрдЭреЗ рд▓рд┐рдЦрдирд╛ рд╣реЛрдЧрд╛:
template <class T, class...Ts> constexpr auto contains(type_pack<Ts...>, type_identity<T> v) { return ((type_identity<Ts>{} == v) or ...); }
- рд╕реБрдкрд░рдлрд╝реНрд▓рд╕ рдкреНрд░рдХрд╛рд░ рдХреЗ рдмрд┐рдирд╛ рд╕рднреА рдореИрдХреНрд░реЛрдЬрд╝ рдЧрд╛рдпрдм рд╣реЛ рдЧрдП
- рдореИрдВ рд╡рд┐рдзрд┐ рдХреЗ рд▓рд┐рдП рддрд░реНрдХреЛрдВ рдХреЛ рдХреЙрдиреНрд╕реНрдЯреНрд░реЗрдХреНрд╕ рд╕рдВрджрд░реНрдн рдореЗрдВ рдЙрдирдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддрд░реНрдХ рджреЗрддрд╛ рд╣реВрдВ
- рдЕрдм рд╕реЗрдЯ рд╡рд┐рдзрд┐ рдореЗрдВ рдХреЙрдиреНрд╕рдЯреЗрдХреНрдк рд▓реЙрдЬрд┐рдХ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд░рд┐рдХреЙрд░реНрдб рдХреЗ рд▓реЙрдЬрд┐рдХ рд╕реЗ рдЕрд▓рдЧ рд╣реЛ рдЧрдпрд╛ рд╣реИ
template<auto...args> static void set() { constexpr auto values_for_write = extract(registers, args...); for (auto [value, offset] : values_for_write) { write(Address::value + offset, value); } }
- рдПрдХреНрд╕реНрдЯреНрд░реЗрдХреНрдЯ рдлрд╝рдВрдХреНрд╢рди рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдХреЛ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдореВрд▓реНрдпреЛрдВ рдХреА рдПрдХ рд╕рд░рдгреА рдХреЙрдиреНрд╕реНрдЯреИрдХреНрд╕ рдореЗрдВ рдЖрд╡рдВрдЯрд┐рдд рдХрд░рддрд╛ рд╣реИред рдЗрд╕рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкрд┐рдЫрд▓реЗ рд╕реЗрдЯ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╕рдорд╛рди рд╣реИ, рд╕рд┐рд╡рд╛рдп рдЗрд╕рдХреЗ рдХрд┐ рдпрд╣ рд░рдЬрд┐рд╕реНрдЯрд░ рдореЗрдВ рд╕реАрдзреЗ рдирд╣реАрдВ рд▓рд┐рдЦрддрд╛ рд╣реИред
- рдореБрдЭреЗ рдПрдХ рдЕрдиреНрдп рдореЗрдЯрд╛рдлрд╝рдВрдХреНрд╢рди рдЬреЛрдбрд╝рдирд╛ рдерд╛ рдЬреЛ рдЯрд╛рдЗрдк_рдкреИрдХ рдХреЛ рд▓реИрдВрдмрдбрд╛ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдПрдХ рд╕рд░рдгреА рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рддрд╛ рд╣реИред
template <class F, class...Ts> constexpr auto to_array(type_pack<Ts...> pack, F f) { return std::array{f(type_identity<Ts>{})...}; }