1 // Copyright 2013 Google Inc. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS-IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 16 // Original author: ericv@google.com (Eric Veach) 17 // Converted to D: madric@gmail.com (Vijay Nayar) 18 19 module s2.s2error; 20 21 import std.format : format; 22 23 /** 24 * S2Error is a simple class consisting of an error code and a human-readable 25 * error message. 26 * 27 * This class is intended to be copied by value as desired. It uses 28 * the default copy constructor and assignment operator. 29 */ 30 struct S2Error { 31 private: 32 Code _code = Code.OK; 33 string _text; 34 35 public: 36 enum Code { 37 OK = 0, // No error. 38 39 //////////////////////////////////////////////////////////////////// 40 // Generic errors, not specific to geometric objects: 41 42 UNKNOWN = 1000, // Unknown error. 43 UNIMPLEMENTED = 1001, // Operation is not implemented. 44 OUT_OF_RANGE = 1002, // Argument is out of range. 45 INVALID_ARGUMENT = 1003, // Invalid argument (other than a range error). 46 FAILED_PRECONDITION = 1004, // Object is not in the required state. 47 INTERNAL = 1005, // An internal invariant has failed. 48 DATA_LOSS = 1006, // Data loss or corruption. 49 RESOURCE_EXHAUSTED = 1007, // A resource has been exhausted. 50 51 //////////////////////////////////////////////////////////////////// 52 // Error codes in the following range can be defined by clients: 53 54 USER_DEFINED_START = 1000000, 55 USER_DEFINED_END = 9999999, 56 57 //////////////////////////////////////////////////////////////////// 58 // Errors that apply to more than one type of geometry: 59 60 NOT_UNIT_LENGTH = 1, // Vertex is not unit length. 61 DUPLICATE_VERTICES = 2, // There are two identical vertices. 62 ANTIPODAL_VERTICES = 3, // There are two antipodal vertices. 63 64 //////////////////////////////////////////////////////////////////// 65 // S2Loop errors: 66 67 LOOP_NOT_ENOUGH_VERTICES = 100, // Loop with fewer than 3 vertices. 68 LOOP_SELF_INTERSECTION = 101, // Loop has a self-intersection. 69 70 //////////////////////////////////////////////////////////////////// 71 // S2Polygon errors: 72 73 POLYGON_LOOPS_SHARE_EDGE = 200, // Two polygon loops share an edge. 74 POLYGON_LOOPS_CROSS = 201, // Two polygon loops cross. 75 POLYGON_EMPTY_LOOP = 202, // Polygon has an empty loop. 76 POLYGON_EXCESS_FULL_LOOP = 203, // Non-full polygon has a full loop. 77 78 // InitOriented() was called and detected inconsistent loop orientations. 79 POLYGON_INCONSISTENT_LOOP_ORIENTATIONS = 204, 80 81 // Loop depths don't correspond to any valid nesting hierarchy. 82 POLYGON_INVALID_LOOP_DEPTH = 205, 83 84 // Actual polygon nesting does not correspond to the nesting hierarchy 85 // encoded by the loop depths. 86 POLYGON_INVALID_LOOP_NESTING = 206, 87 88 //////////////////////////////////////////////////////////////////// 89 // S2Builder errors: 90 91 // The S2Builder snap function moved a vertex by more than the specified 92 // snap radius. 93 BUILDER_SNAP_RADIUS_TOO_SMALL = 300, 94 95 // S2Builder expected all edges to have siblings (as specified by 96 // S2Builder::GraphOptions::SiblingPairs::REQUIRE), but some were missing. 97 BUILDER_MISSING_EXPECTED_SIBLING_EDGES = 301, 98 99 // S2Builder found an unexpected degenerate edge. For example, 100 // Graph::GetLeftTurnMap() does not support degenerate edges. 101 BUILDER_UNEXPECTED_DEGENERATE_EDGE = 302, 102 103 // S2Builder found a vertex with (indegree != outdegree), which means 104 // that the given edges cannot be assembled into loops. 105 BUILDER_EDGES_DO_NOT_FORM_LOOPS = 303, 106 107 // The edges provided to S2Builder cannot be assembled into a polyline. 108 BUILDER_EDGES_DO_NOT_FORM_POLYLINE = 304, 109 110 // There was an attempt to assemble a polygon from degenerate geometry 111 // without having specified a predicate to decide whether the output is 112 // the empty polygon (containing no points) or the full polygon 113 // (containing all points). 114 BUILDER_IS_FULL_PREDICATE_NOT_SPECIFIED = 305, 115 } 116 117 // Set the error to the given code and printf-style message. Note that you 118 // can prepend text to an existing error by calling Init() more than once: 119 // 120 // error->Init(error->code(), "Loop %d: %s", j, error->text().c_str()); 121 void initialize(T...)(Code code, string fmt, T args) { 122 _code = code; 123 _text ~= format(fmt, args); 124 } 125 126 bool ok() const { 127 return _code == Code.OK; 128 } 129 130 Code code() const { 131 return _code; 132 } 133 134 string text() const { 135 return _text; 136 } 137 138 // Clear the error to contain the OK code and no error message. 139 void clear() { 140 _code = Code.OK; 141 _text = ""; 142 } 143 144 string toString() const { 145 return _text; 146 } 147 148 }