online compiler and debugger for c/c++

code. compile. run. debug. share.
Source Code   
Language
#include <iostream> #include "const_string.h" #include "const_map.h" #include <iostream> #include "const_string.h" #include "const_map.h" namespace midi_details { using data_t = char; using string_t = const_string<32>; } constexpr midi_details::data_t MIDI_NOTE_OFF = 8; constexpr midi_details::data_t MIDI_NOTE_ON = 9; constexpr midi_details::data_t MIDI_KEY_AFTERTOUCH = 10; constexpr midi_details::data_t MIDI_CONTROL_CHANGE = 11; constexpr midi_details::data_t MIDI_PROGRAM_CHANGE = 12; constexpr midi_details::data_t MIDI_CHANNEL_AFTERTOUCH = 13; constexpr midi_details::data_t MIDI_PITCH_WHEEL_CHANGE = 14; namespace midi_details { constexpr auto required_bytes = make_const_map<data_t, data_t>({ {MIDI_NOTE_OFF,2}, {MIDI_NOTE_ON,2}, {MIDI_KEY_AFTERTOUCH,2}, {MIDI_CONTROL_CHANGE,2}, {MIDI_PROGRAM_CHANGE,1}, {MIDI_CHANNEL_AFTERTOUCH,1}, {MIDI_PITCH_WHEEL_CHANGE,2} }); constexpr auto str = make_const_map<data_t, string_t>({ { MIDI_NOTE_ON,"Note on" }, { MIDI_NOTE_OFF,"Note off" }, { MIDI_CONTROL_CHANGE, "Control change"}, { MIDI_CHANNEL_AFTERTOUCH, "Channel aftertouch"}, { MIDI_PITCH_WHEEL_CHANGE, "Pitch wheel change"} }); struct info_t { constexpr info_t(data_t r, string_t n) : required_bytes{ r }, name{ n } { } data_t required_bytes; string_t name; }; } /* namespace midi_details */ constexpr auto midi(midi_details::data_t value) { return midi_details::info_t{ midi_details::required_bytes[value], midi_details::str[value] }; } int main() { static_assert(MIDI_NOTE_OFF == 8); static_assert(midi(MIDI_NOTE_OFF).required_bytes == 2, "test failed"); static_assert(midi(MIDI_NOTE_OFF).name == "Note off", "test failed"); return 0; }
//--------------------------------------------------------------------------------------------------------------------- // // const_map.h // This header file implements a compile time map (key value pairs) // it will take up n*sizeof(key-value pair) memory at compile time. // //--------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2021 Pepijn Kramer // // This program 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, version 3. (https://www.gnu.org/licenses/lgpl-3.0.en.html) // // This code 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 // General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. // #pragma once #include "const_set.h" template<typename key_t, typename value_t> struct kv_pair_t final { kv_pair_t() = default; constexpr kv_pair_t(const key_t& k, const value_t& v) : key{ k }, value{ v } { }; key_t key{}; value_t value{}; constexpr bool operator>(const kv_pair_t& rhs) const { return key > rhs.key; } constexpr bool operator<(const kv_pair_t& rhs) const { return key < rhs.key; } constexpr bool operator==(const kv_pair_t& rhs) const { return key == rhs.key; } }; template<typename key_t, typename value_t, std::size_t N> class const_map { public: using pair_t = kv_pair_t<key_t, value_t>; constexpr const_map(const pair_t(&pairs)[N]) : m_set(pairs) { } constexpr const value_t& operator[](const key_t& key) const { kv_pair_t<key_t, value_t> k{ key,{} }; return m_set[k].value; } private: const_set<pair_t, N> m_set; }; template<typename key_t, typename value_t, std::size_t N> constexpr auto make_const_map(const kv_pair_t<key_t, value_t>(&pairs)[N]) { return const_map<key_t, value_t, N>(pairs); }
//--------------------------------------------------------------------------------------------------------------------- // // const_set.h // // This header file implements a compile time ordered set // Insertion will work in O(n) time // The contains operation works in O(log n) time // Adding a non unique value will result in a failure (std::invalid_argument exception) // //--------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2021 Pepijn Kramer // // This program 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, version 3. (https://www.gnu.org/licenses/lgpl-3.0.en.html) // // This code 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 // General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. // #pragma once #include <cassert> #include <stdexcept> //--------------------------------------------------------------------------------------------------------------------- namespace details { // helper struct, determines a span in which to look for a value struct span_t { constexpr span_t(const size_t new_from, const size_t new_to) : from{ new_from }, to{ new_to }, mid{ (from + to) / 2 } { } constexpr span_t left() { size_t new_to = (mid > to) ? mid - 1 : mid; return span_t(from, new_to); } constexpr span_t right() { size_t new_from = (from < mid) ? mid : mid + 1; return span_t(new_from, to); } size_t from; size_t to; size_t mid; }; } //--------------------------------------------------------------------------------------------------------------------- template<typename type_t, std::size_t N> class const_set { public: constexpr const_set(const type_t(&list)[N]) : m_values{} { for (const auto& v : list) insert(v); } // add begin end operations so collection can be used in range based for loops constexpr auto begin() const { return std::begin(m_values); } constexpr auto end() const { return std::end(m_values); } constexpr bool contains(const type_t& value) const { details::span_t span{ 0, N - 1 }; do { if (m_values[span.mid] == value) { return true; } span = (value > m_values[span.mid]) ? span.right() : span.left(); assert(span.mid < N); } while (span.from != span.to); return (m_values[span.mid] == value); } constexpr const type_t& operator[](const type_t& value) const { details::span_t span{ 0, N - 1 }; do { if (m_values[span.mid] == value) { return m_values[span.mid]; } span = (value > m_values[span.mid]) ? span.right() : span.left(); assert(span.mid < N); } while (span.from != span.to); return (m_values[span.mid] == value) ? m_values[span.mid] : default_value; } private: // insert in ascending order, doesn't have to be very smart // only done at compile time. inline constexpr void insert(const type_t& value) { std::size_t pos{ 0 }; if (m_size != 0) { while ((pos < m_size) && (value > m_values[pos])) pos++; if (m_values[pos] == value) // { throw std::invalid_argument("value is not unique, set cannot be build"); } // shift content to back if (pos < m_size) { for (std::size_t m = N - 1; m > pos; --m) { m_values[m] = std::move(m_values[m - 1]); } } } m_values[pos] = value; ++m_size; } type_t m_values[N]; type_t default_value{}; std::size_t m_size = 0; }; template<typename type_t, std::size_t N> constexpr auto make_const_set(const type_t(&list)[N]) { return const_set<type_t, N>(list); }
//--------------------------------------------------------------------------------------------------------------------- // // const_string.h // // This header file implements a minimal compile time constant string // //--------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2021 Pepijn Kramer // // This program 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, version 3. (https://www.gnu.org/licenses/lgpl-3.0.en.html) // // This code 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 // General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. // #pragma once #include <algorithm> #include <array> #include <iostream> //------------------------------------------------------------------------------------------------- // Helper class to hold a string of maximum capacity at compile time. template<std::size_t string_capacity_v = 128> class const_string { public: constexpr const_string() = default; ~const_string() = default; constexpr const_string(const const_string&) = default; template<std::size_t string_length> constexpr const_string(const char(&str)[string_length]) : m_str{} { for (std::size_t n = 0; n < std::min(string_capacity_v, string_length); ++n) m_str[n] = str[n]; } constexpr const char* c_str() const noexcept { return m_str; } constexpr std::size_t capacity() const noexcept { return string_capacity_v; } private: char m_str[string_capacity_v]{}; }; template<std::size_t string_capacity_v> constexpr bool operator==(const const_string<string_capacity_v>& lhs, const const_string<string_capacity_v>& rhs) { std::size_t n = 0; auto l = lhs.c_str(); auto r = rhs.c_str(); while ((l[n] == r[n]) && (n < string_capacity_v) && (l[n] != 0) && (r[n] != 0) ) ++n; return l[n] == r[n]; } template<std::size_t string_capacity_v, std::size_t str_len> constexpr bool operator==(const const_string<string_capacity_v>& lhs, const char(&rhs)[str_len]) { std::size_t n = 0; auto rstr = const_string<string_capacity_v>(rhs); return (lhs == rstr); } template<std::size_t string_capacity_v> std::ostream& operator<<(std::ostream& os, const const_string<string_capacity_v>& cstr) { return os << cstr.str(); }

Compiling Program...

Command line arguments:
Standard Input: Interactive Console Text

                

                

Program is not being debugged. Click "Debug" button to start program in debug mode.

#FunctionFile:Line
VariableValue
RegisterValue
ExpressionValue