Copying ast::variant?

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Copying ast::variant?

Mario Lang
Hi.

Does this error (with gcc 5) ring a bell for anyone?  I am stuck here.
I don't quite understand the error.  Why should a move constructor imply
a deleted copy constructor?

/usr/include/c++/5/bits/stl_construct.h:75:7: error: use of deleted function ‘bmc::braille::parser::ast::sign::sign(const bmc::braille::parser::ast::sign&)’
     { ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
       ^
In file included from /tmp/src/bmc/include/bmc/braille/parser/ast_adapted.hpp:4:0,
                 from /tmp/src/bmc/parser.cpp:1:
/tmp/src/bmc/include/bmc/braille/parser/ast.hpp:249:8: note: ‘bmc::braille::parser::ast::sign::sign(const bmc::braille::parser::ast::sign&)’ is implicitly declared as deleted because ‘bmc::braille::parser::ast::sign’ declares a move constructor or move assignment operator

bmc::braille::parser::ast::sign is defined like the typical boilerplate
X3 variant:

struct sign : variant<a, number, of, types, ...> {
  using base_type::base_type;
  using base_type::operator=;
};

For completeness sake, my ast.hpp is appended.

#if !defined(BMC_BRAILLE_PARSER_AST_HPP)
#define BMC_BRAILLE_PARSER_AST_HPP

#include <bmc/music.hpp>
#include <bmc/braille_music.hpp>
#include <boost/optional.hpp>
#include <boost/rational.hpp>
#include <boost/spirit/home/x3/support/ast/position_tagged.hpp>
#include <boost/spirit/home/x3/support/ast/variant.hpp>

namespace bmc { namespace braille { namespace parser { namespace ast {

using boost::spirit::x3::position_tagged;
using boost::spirit::x3::variant;

struct time_signature : position_tagged
{
  int numerator;
  int denominator;

  operator boost::rational<int>() const { return {numerator, denominator}; }
};

struct key_signature : position_tagged
{
  int fifths;
};

enum ambiguous_value
{
  whole_or_16th, half_or_32th, quarter_or_64th, eighth_or_128th, unknown_ambiguous_value
};

enum class notegroup_member_type: uint8_t {
  none, begin, middle, end
};

enum class slur_member_type: uint8_t {
  none, begin, middle, end
};

struct rhythmic_storage
{
  ast::ambiguous_value ambiguous_value = unknown_ambiguous_value;
  unsigned dots = 0;
  rational type = rational(); // filled in by value_disambiguation.hpp
  rational factor = rational(1);
  notegroup_member_type notegroup_member = notegroup_member_type::none; // filled in by value_disambiguation.hpp
  slur_member_type slur_member = slur_member_type::none;
  std::vector<rational> tuplet_begin;
  unsigned tuplet_end = 0;
};

class rhythmic
{
protected:
  virtual ~rhythmic() {};
public:
  virtual rational as_rational() const = 0;
  virtual unsigned get_dots() const = 0;
  virtual rational get_type() const = 0;
  virtual rational get_factor() const = 0;
};

struct slur final : position_tagged
{
  enum type { single, cross_staff };
  type value;
};

struct tie final : position_tagged
{
  enum type { single, chord, arpeggio };
  type value;
};

struct hand_sign final : position_tagged
{
  enum type { right_hand, left_hand };
  type value;
};

struct pitched
{
  boost::optional<accidental> acc;
  boost::optional<unsigned> octave_spec;
  unsigned octave;
  diatonic_step step;
  int alter;
  boost::optional<ast::tie> tie;
};

struct stem final : rhythmic
{
  rational type;
  unsigned dots;
  boost::optional<ast::tie> tied;

  rational as_rational() const override
  { return type * augmentation_dots_factor(dots); }
  unsigned get_dots() const override
  { return dots; }
  rational get_factor() const override { return 1; }
  rational get_type() const override { return type; }
};

struct note final : position_tagged, rhythmic_storage, rhythmic, pitched
{
  std::vector<articulation> articulations;
  std::vector<slur> slurs;
  fingering_list fingers;
  std::vector<stem> extra_stems;

//  note(): position_tagged(), rhythmic_storage(), pitched() {}
  rational as_rational() const override
  { return type * augmentation_dots_factor(dots) * factor; }
  unsigned get_dots() const override { return dots; }
  rational get_factor() const override { return factor; }
  rational get_type() const override { return type; }
};

struct rest final : position_tagged, rhythmic_storage, rhythmic
{
  bool by_transcriber;

  //rest(): position_tagged(), rhythmic_storage(), whole_measure(false) {}
  virtual ~rest();

  bool whole_measure; // filled in by disambiguate.hpp

  rational as_rational() const override
  { return type * augmentation_dots_factor(dots) * factor; }
  unsigned get_dots() const override
  { return dots; }
  rational get_factor() const override { return factor; }
  rational get_type() const override
  { return whole_measure? rational{1}: type; }
};

struct interval : position_tagged, pitched
{
  ::bmc::interval steps;
  fingering_list fingers;
};

struct chord final : position_tagged, rhythmic
{
  note base;
  std::vector<interval> intervals;
  bool all_tied = false;

  rational as_rational() const override { return base.as_rational(); }
  unsigned get_dots() const override { return base.get_dots(); }
  rational get_factor() const override { return base.get_factor(); }
  rational get_type() const override { return base.get_type(); }

  enum class arpeggio_type { up, down };
  boost::optional<arpeggio_type> arpeggio() const {
    if (std::find(base.articulations.begin(), base.articulations.end(),
                  ::bmc::arpeggio_up) != base.articulations.end())
      return arpeggio_type::up;
    if (std::find(base.articulations.begin(), base.articulations.end(),
                  ::bmc::arpeggio_down) != base.articulations.end())
      return arpeggio_type::down;
    return {};
  }
};

struct moving_note final : position_tagged, rhythmic
{
  note base;
  std::vector<interval> intervals;

  rational as_rational() const override { return base.as_rational(); }
  unsigned get_dots() const override { return base.get_dots(); }
  rational get_factor() const override { return base.get_factor(); }
  rational get_type() const override { return base.get_type(); }
};

struct value_distinction : position_tagged
{
  enum type { distinct, large_follows, small_follows };
  type value;
};

struct hyphen : position_tagged {};

struct simile : position_tagged
{
  boost::optional<unsigned> octave_spec;
  unsigned count;

  rational duration;                    // Filled by value_disambiguation
};

struct barline : position_tagged
{
  enum type { begin_repeat, end_repeat, end_part };
  type value;
};

class tuplet_start : public position_tagged
{
  bool simple_triplet_;
  bool doubled_;
  unsigned number_;
public:
  tuplet_start(bool doubled = false)
  : simple_triplet_{true}, doubled_{doubled} {}
  tuplet_start(unsigned number, bool doubled)
  : simple_triplet_{false}, doubled_{doubled}, number_{number} {}
  tuplet_start(tuplet_start const &) = default;

  unsigned number() const { return simple_triplet_? 3: number_; }
  bool simple_triplet() const { return simple_triplet_; }
  bool doubled() const { return doubled_; }
};

class clef : public position_tagged
{
public:
  enum class type { G, C, F };
private:
  type sign_;
  boost::optional<unsigned> line_;
  boost::optional<unsigned> staff_;
public:
  clef(): sign_{type::G} {}
  clef(type sign): sign_{sign} {}
  clef(type sign, unsigned line): sign_{sign}, line_{line} {}
  clef(clef const &) = default;

  type sign() const { return sign_; }
  unsigned line() const {
    if (line_) return *line_;
    switch(sign_) {
    case type::G: return 2;
    case type::F: return 4;
    case type::C: return 3;
    }
  }
  clef &staff(boost::optional<unsigned> const &n) {
    staff_ = n;
    return *this;
  }
  boost::optional<unsigned> const &staff() const { return staff_; }
};

struct sign : variant<
  note, rest, chord, moving_note
, value_distinction, hyphen, tie, tuplet_start
, hand_sign, clef, simile, barline
>
{
  using base_type::base_type;
  using base_type::operator=;
};

struct partial_voice : position_tagged, std::vector<sign> {};
struct partial_measure : position_tagged, std::vector<partial_voice> {};
struct voice : position_tagged, std::vector<partial_measure> {};

struct measure : position_tagged
{
  boost::optional<unsigned> ending;
  std::vector<voice> voices;
};

struct key_and_time_signature : position_tagged
{
  key_signature key;
  time_signature time;
};

struct paragraph_element : variant<
  measure, key_and_time_signature
>
{};

struct paragraph : position_tagged, std::vector<paragraph_element> {};

struct measure_specification : position_tagged
{
  typedef unsigned number_type;
  number_type number;
  boost::optional<number_type> alternative;
};

struct measure_range : position_tagged
{
  measure_specification first;
  measure_specification last;
};

struct section : position_tagged
{
  typedef unsigned number_type;
  boost::optional<key_and_time_signature> key_and_time_sig;
  boost::optional<number_type> number;
  boost::optional<measure_range> range;
  std::vector<paragraph> paragraphs;
};

struct part : position_tagged, std::vector<section> {};

struct score {
  key_signature key_sig;
  std::vector<time_signature> time_sigs;
  std::vector<part> parts;
};

}}}}

#endif


--
CYa,
  ⡍⠁⠗⠊⠕

------------------------------------------------------------------------------
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: Copying ast::variant?

Joel de Guzman
On 5/27/15 11:36 PM, Mario Lang wrote:

> Hi.
>
> Does this error (with gcc 5) ring a bell for anyone?  I am stuck here.
> I don't quite understand the error.  Why should a move constructor imply
> a deleted copy constructor?
>
> /usr/include/c++/5/bits/stl_construct.h:75:7: error: use of deleted function ‘bmc::braille::parser::ast::sign::sign(const bmc::braille::parser::ast::sign&)’
>       { ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
>         ^
> In file included from /tmp/src/bmc/include/bmc/braille/parser/ast_adapted.hpp:4:0,
>                   from /tmp/src/bmc/parser.cpp:1:
> /tmp/src/bmc/include/bmc/braille/parser/ast.hpp:249:8: note: ‘bmc::braille::parser::ast::sign::sign(const bmc::braille::parser::ast::sign&)’ is implicitly declared as deleted because ‘bmc::braille::parser::ast::sign’ declares a move constructor or move assignment operator
>

Nothing obvious. If you can minimize the test case, I can look into it.

Regards,
--
Joel de Guzman
http://www.ciere.com
http://boost-spirit.com
http://www.cycfi.com/


------------------------------------------------------------------------------
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general