Commit Graph

11 Commits (23feb4cf8f22341c1f47810c9955a9b8475a14e6)

Author SHA1 Message Date
EvilSpirit 600c39db91 Don't consider arc center point for bounding box calculation. 2016-11-02 02:40:26 +00:00
whitequark 8aab0160d3 Refactor EntReqTable to not special-case last row.
Simplify it a bit while we're at it.
2016-05-26 12:43:52 +00:00
whitequark 1249f8496e Enable exhaustive switch coverage warnings as an error, and use them.
Specifically, this enables -Wswitch=error on GCC/Clang and its MSVC
equivalent; the exact way it is handled varies slightly, but what
they all have in common is that in a switch statement over an
enumeration, any enumerand that is not explicitly (via case:) or
implicitly (via default:) handled in the switch triggers an error.

Moreover, we also change the switch statements in three ways:

  * Switch statements that ought to be extended every time a new
    enumerand is added (e.g. Entity::DrawOrGetDistance(), are changed
    to explicitly list every single enumerand, and not have a
    default: branch.

    Note that the assertions are kept because it is legal for
    a enumeration to have a value unlike any of its defined
    enumerands, and we can e.g. read garbage from a file, or
    an uninitialized variable. This requires some rearranging if
    a default: branch is undesired.

  * Switch statements that ought to only ever see a few select
    enumerands, are changed to always assert in the default: branch.

  * Switch statements that do something meaningful for a few
    enumerands, and ignore everything else, are changed to do nothing
    in a default: branch, under the assumption that changing them
    every time an enumerand is added or removed would just result
    in noise and catch no bugs.

This commit also removes the {Request,Entity,Constraint}::UNKNOWN and
Entity::DATUM_POINT enumerands, as those were just fancy names for
zeroes. They mess up switch exhaustiveness checks and most of the time
were not the best way to implement what they did anyway.
2016-05-26 12:43:52 +00:00
EvilSpirit f33ddc94fb Convert all enumerations to use `enum class`.
Specifically, take the old code that looks like this:

  class Foo {
    enum { X = 1, Y = 2 };
    int kind;
  }
  ... foo.kind = Foo::X; ...

and convert it to this:

  class Foo {
    enum class Kind : uint32_t { X = 1, Y = 2 };
    Kind kind;
  }
  ... foo.kind = Foo::Kind::X;

(In some cases the enumeration would not be in the class namespace,
such as when it is generally useful.)

The benefits are as follows:
  * The type of the field gives a clear indication of intent, both
    to humans and tools (such as binding generators).
  * The compiler is able to automatically warn when a switch is not
    exhaustive; but this is currently suppressed by the
      default: ssassert(false, ...)
    idiom.
  * Integers and plain enums are weakly type checked: they implicitly
    convert into each other. This can hide bugs where type conversion
    is performed but not intended. Enum classes are strongly type
    checked.
  * Plain enums pollute parent namespaces; enum classes do not.
    Almost every defined enum we have already has a kind of ad-hoc
    namespacing via `NAMESPACE_`, which is now explicit.
  * Plain enums do not have a well-defined ABI size, which is
    important for bindings. Enum classes can have it, if specified.
    We specify the base type for all enums as uint32_t, which is
    a safe choice and allows us to not change the numeric values
    of any variants.

This commit introduces absolutely no functional change to the code,
just renaming and change of types. It handles almost all cases,
except GraphicsWindow::pending.operation, which needs minor
functional change.
2016-05-25 07:17:14 +00:00
whitequark 20d87d93c5 Add const qualifiers to functions where trivially possible.
This will allow us in future to accept `const T &` anywhere it's
necessary to reduce the amount of copying.

This commit is quite conservative: it does not attempt very hard to
refactor code that performs incidental mutation. In particular
dogd and caches are not marked with the `mutable` keyword.
dogd will be eliminated later, opening up more opportunities to
add const qualifiers.

This commit also doesn't introduce any uses of the newly added const
qualifers. This will be done later.
2016-05-25 03:22:54 +00:00
EvilSpirit bbca4cc224 Rewrite declarations of form f(void) as f().
In C++ there is no difference and newly added functions are all
declared as f(), so this brings back consistency.
2016-05-20 12:43:20 +00:00
whitequark ad4a204edf Replace all oops() checks with ssassert()s.
This includes explanation and context for non-obvious cases and
shortens debug cycles when just-in-time debugging is not available
(like on Linux) by immediately printing description of the assert
as well as symbolized backtrace.
2016-05-20 12:38:30 +00:00
EvilSpirit 77d8291216 Allow removing spline points. 2016-04-15 06:11:03 +00:00
whitequark 11f29b1231 Replace NameStr with std::string.
This removes the arbitrary 64 byte restriction (which effectively
limits us to as little as 16 Unicode characters with CJK encodings),
makes classes smaller, and is easier to use.

As a consequence of making the length of all ex-NameStr fields
unbounded, all functions that returned a buffer derived from those
were changed to return std::string. Then, functions that are
contextually similar to the ones described above were changed
to return std::string. Then, functions that now happened to mostly
take an std::string argument converted to a C string were changed
to accept std::string.

This has produced a bit of churn, but is probably for the better.
2016-01-13 06:45:17 +00:00
whitequark 45f056c852 Replace all ZERO and memset with C++11 brace-initialization.
This will allow us to use non-POD classes inside these objects
in future and is otherwise functionally equivalent, as well
as more concise.

Note that there are some subtleties with handling of
brace-initialization. Specifically:

On aggregates (e.g. simple C-style structures) using an empty
brace-initializer zero-initializes the aggregate, i.e. it makes
all members zero.

On non-aggregates an empty brace-initializer calls the default
constructor. And if the constructor doesn't explicitly initialize
the members (which the auto-generated constructor doesn't) then
the members will be constructed but otherwise uninitialized.

So, what is an aggregate class? To quote the C++ standard
(C++03 8.5.1 §1):

An aggregate is an array or a class (clause 9) with no
user-declared constructors (12.1), no private or protected
non-static data members (clause 11), no base classes (clause 10),
and no virtual functions (10.3).

In SolveSpace, we only have to handle the case of base classes;
Constraint and Entity have those. Thus, they had to gain a default
constructor that does nothing but initializes the members to zero.
2016-01-13 06:45:16 +00:00
Daniel Richard G 0a24cf40f0 Moved most of the source into a src/ subdirectory
The SolveSpace top-level directory was getting a bit cluttered, so
following the example of numerous other free-software projects, we move the
main application source into a subdirectory and adjust the build systems
accordingly.

Also, got rid of the obj/ directory in favor of creating it on the fly in
Makefile.msvc.
2013-11-19 18:17:32 -05:00